@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,343 @@
1
+ import {
2
+ type AnchorPosition,
3
+ type DismissableLayer,
4
+ type Placement,
5
+ type Presence,
6
+ createAnchorPosition,
7
+ createDismissableLayer,
8
+ createPresence,
9
+ prefersReducedMotion,
10
+ } from "@hypoth-ui/primitives-dom";
11
+ import { html } from "lit";
12
+ import { property } from "lit/decorators.js";
13
+ import { DSElement } from "../../base/ds-element.js";
14
+ import { StandardEvents, emitEvent } from "../../events/emit.js";
15
+ import { define } from "../../registry/define.js";
16
+
17
+ // Import child component to ensure it's registered
18
+ import type { DsPopoverContent } from "./popover-content.js";
19
+ import "./popover-content.js";
20
+
21
+ /**
22
+ * Non-modal popover component with anchor positioning.
23
+ *
24
+ * Unlike Dialog, Popover does not trap focus and allows Tab to exit.
25
+ * Positioned relative to its trigger using anchor positioning.
26
+ *
27
+ * @element ds-popover
28
+ *
29
+ * @slot trigger - Button or element that opens the popover
30
+ * @slot - Popover content (ds-popover-content)
31
+ *
32
+ * @fires ds:open - Fired when popover opens
33
+ * @fires ds:close - Fired when popover closes
34
+ *
35
+ * @example
36
+ * ```html
37
+ * <ds-popover>
38
+ * <button slot="trigger">Open Menu</button>
39
+ * <ds-popover-content>
40
+ * <button>Option 1</button>
41
+ * <button>Option 2</button>
42
+ * </ds-popover-content>
43
+ * </ds-popover>
44
+ * ```
45
+ */
46
+ export class DsPopover extends DSElement {
47
+ /** Whether the popover is open */
48
+ @property({ type: Boolean, reflect: true })
49
+ open = false;
50
+
51
+ /** Placement relative to trigger */
52
+ @property({ type: String, reflect: true })
53
+ placement: Placement = "bottom";
54
+
55
+ /** Offset distance from trigger in pixels */
56
+ @property({ type: Number })
57
+ offset = 8;
58
+
59
+ /** Whether to flip placement when near viewport edge */
60
+ @property({ type: Boolean })
61
+ flip = true;
62
+
63
+ /** Whether Escape key closes the popover */
64
+ @property({
65
+ attribute: "close-on-escape",
66
+ converter: {
67
+ fromAttribute: (value: string | null) => value !== "false",
68
+ toAttribute: (value: boolean) => (value ? "" : "false"),
69
+ },
70
+ })
71
+ closeOnEscape = true;
72
+
73
+ /** Whether clicking outside closes the popover */
74
+ @property({
75
+ attribute: "close-on-outside-click",
76
+ converter: {
77
+ fromAttribute: (value: string | null) => value !== "false",
78
+ toAttribute: (value: boolean) => (value ? "" : "false"),
79
+ },
80
+ })
81
+ closeOnOutsideClick = true;
82
+
83
+ /** Whether to animate open/close transitions */
84
+ @property({ type: Boolean })
85
+ animated = true;
86
+
87
+ private anchorPosition: AnchorPosition | null = null;
88
+ private dismissLayer: DismissableLayer | null = null;
89
+ private presence: Presence | null = null;
90
+ private triggerElement: HTMLElement | null = null;
91
+ private resizeObserver: ResizeObserver | null = null;
92
+ private scrollHandler: (() => void) | null = null;
93
+
94
+ override connectedCallback(): void {
95
+ super.connectedCallback();
96
+
97
+ // Listen for trigger clicks
98
+ this.addEventListener("click", this.handleTriggerClick);
99
+
100
+ // Setup after first render
101
+ this.updateComplete.then(() => {
102
+ this.setupTriggerAccessibility();
103
+ });
104
+ }
105
+
106
+ override disconnectedCallback(): void {
107
+ super.disconnectedCallback();
108
+ this.removeEventListener("click", this.handleTriggerClick);
109
+ this.cleanup();
110
+ }
111
+
112
+ /**
113
+ * Opens the popover.
114
+ */
115
+ public show(): void {
116
+ if (this.open) return;
117
+
118
+ this.open = true;
119
+ emitEvent(this, StandardEvents.OPEN);
120
+ }
121
+
122
+ /**
123
+ * Closes the popover.
124
+ */
125
+ public close(): void {
126
+ if (!this.open) return;
127
+
128
+ const content = this.querySelector("ds-popover-content") as DsPopoverContent | null;
129
+
130
+ // If animated, use presence for exit animation
131
+ if (this.animated && content && !prefersReducedMotion()) {
132
+ // Cleanup dismiss layer so clicks don't re-trigger close
133
+ this.dismissLayer?.deactivate();
134
+ this.dismissLayer = null;
135
+
136
+ // Create presence for exit animation
137
+ this.presence = createPresence({
138
+ onExitComplete: () => {
139
+ this.completeClose();
140
+ },
141
+ });
142
+ this.presence.hide(content);
143
+ } else {
144
+ // No animation - close immediately
145
+ this.cleanup();
146
+ this.open = false;
147
+ emitEvent(this, StandardEvents.CLOSE);
148
+
149
+ // Return focus to trigger
150
+ this.triggerElement?.focus();
151
+ }
152
+ }
153
+
154
+ /**
155
+ * Completes the close after exit animation.
156
+ */
157
+ private completeClose(): void {
158
+ this.cleanup();
159
+ this.open = false;
160
+ emitEvent(this, StandardEvents.CLOSE);
161
+
162
+ // Return focus to trigger
163
+ this.triggerElement?.focus();
164
+ }
165
+
166
+ /**
167
+ * Toggles the popover open/closed state.
168
+ */
169
+ public toggle(): void {
170
+ if (this.open) {
171
+ this.close();
172
+ } else {
173
+ this.show();
174
+ }
175
+ }
176
+
177
+ private handleTriggerClick = (event: Event): void => {
178
+ const target = event.target as HTMLElement;
179
+ const trigger = target.closest('[slot="trigger"]');
180
+
181
+ if (trigger && this.contains(trigger)) {
182
+ event.preventDefault();
183
+ this.triggerElement = trigger as HTMLElement;
184
+ this.toggle();
185
+ }
186
+ };
187
+
188
+ private handleDismiss = (reason: "escape" | "outside-click"): void => {
189
+ if (reason === "escape" && this.closeOnEscape) {
190
+ this.close();
191
+ } else if (reason === "outside-click" && this.closeOnOutsideClick) {
192
+ this.close();
193
+ }
194
+ };
195
+
196
+ private setupTriggerAccessibility(): void {
197
+ const trigger = this.querySelector('[slot="trigger"]');
198
+ const content = this.querySelector("ds-popover-content");
199
+
200
+ if (trigger && content) {
201
+ // Store reference
202
+ this.triggerElement = trigger as HTMLElement;
203
+
204
+ // Set ARIA attributes on trigger
205
+ trigger.setAttribute("aria-haspopup", "true");
206
+ trigger.setAttribute("aria-expanded", String(this.open));
207
+ trigger.setAttribute("aria-controls", content.id);
208
+ }
209
+ }
210
+
211
+ private updateTriggerAria(): void {
212
+ const trigger = this.querySelector('[slot="trigger"]');
213
+ if (trigger) {
214
+ trigger.setAttribute("aria-expanded", String(this.open));
215
+ }
216
+ }
217
+
218
+ private setupPositioning(): void {
219
+ const trigger = this.querySelector('[slot="trigger"]') as HTMLElement | null;
220
+ const content = this.querySelector("ds-popover-content") as HTMLElement | null;
221
+
222
+ if (!trigger || !content) return;
223
+
224
+ // Setup anchor positioning
225
+ this.anchorPosition = createAnchorPosition({
226
+ anchor: trigger,
227
+ floating: content,
228
+ placement: this.placement,
229
+ offset: this.offset,
230
+ flip: this.flip,
231
+ onPositionChange: (pos) => {
232
+ content.setAttribute("data-placement", pos.placement);
233
+ },
234
+ });
235
+
236
+ // Setup resize observer for repositioning
237
+ this.resizeObserver = new ResizeObserver(() => {
238
+ this.anchorPosition?.update();
239
+ });
240
+ this.resizeObserver.observe(trigger);
241
+ this.resizeObserver.observe(content);
242
+
243
+ // Setup scroll handler for repositioning
244
+ this.scrollHandler = () => {
245
+ this.anchorPosition?.update();
246
+ };
247
+ window.addEventListener("scroll", this.scrollHandler, { passive: true });
248
+ window.addEventListener("resize", this.scrollHandler, { passive: true });
249
+ }
250
+
251
+ private setupDismissLayer(): void {
252
+ const content = this.querySelector("ds-popover-content") as HTMLElement | null;
253
+ const trigger = this.querySelector('[slot="trigger"]') as HTMLElement | null;
254
+
255
+ if (!content) return;
256
+
257
+ this.dismissLayer = createDismissableLayer({
258
+ container: content,
259
+ excludeElements: trigger ? [trigger] : [],
260
+ onDismiss: this.handleDismiss,
261
+ closeOnEscape: this.closeOnEscape,
262
+ closeOnOutsideClick: this.closeOnOutsideClick,
263
+ });
264
+ this.dismissLayer.activate();
265
+ }
266
+
267
+ private cleanup(): void {
268
+ // Cleanup anchor positioning
269
+ this.anchorPosition?.destroy();
270
+ this.anchorPosition = null;
271
+
272
+ // Cleanup dismiss layer
273
+ this.dismissLayer?.deactivate();
274
+ this.dismissLayer = null;
275
+
276
+ // Cleanup presence
277
+ this.presence?.destroy();
278
+ this.presence = null;
279
+
280
+ // Cleanup resize observer
281
+ this.resizeObserver?.disconnect();
282
+ this.resizeObserver = null;
283
+
284
+ // Cleanup scroll handler
285
+ if (this.scrollHandler) {
286
+ window.removeEventListener("scroll", this.scrollHandler);
287
+ window.removeEventListener("resize", this.scrollHandler);
288
+ this.scrollHandler = null;
289
+ }
290
+ }
291
+
292
+ override async updated(changedProperties: Map<string, unknown>): Promise<void> {
293
+ super.updated(changedProperties);
294
+
295
+ if (changedProperties.has("open")) {
296
+ this.updateTriggerAria();
297
+
298
+ const content = this.querySelector("ds-popover-content") as DsPopoverContent | null;
299
+
300
+ if (this.open) {
301
+ // Show content
302
+ content?.removeAttribute("hidden");
303
+
304
+ // Set data-state to open for entry animation
305
+ if (content) {
306
+ content.dataState = "open";
307
+ }
308
+
309
+ // Wait for DOM update
310
+ await this.updateComplete;
311
+
312
+ // Setup positioning and dismiss
313
+ this.setupPositioning();
314
+ this.setupDismissLayer();
315
+ } else {
316
+ // Hide content
317
+ content?.setAttribute("hidden", "");
318
+ }
319
+ }
320
+
321
+ // Update positioning if placement or offset changes while open
322
+ if (this.open && (changedProperties.has("placement") || changedProperties.has("offset"))) {
323
+ this.cleanup();
324
+ this.setupPositioning();
325
+ this.setupDismissLayer();
326
+ }
327
+ }
328
+
329
+ override render() {
330
+ return html`
331
+ <slot name="trigger"></slot>
332
+ <slot></slot>
333
+ `;
334
+ }
335
+ }
336
+
337
+ define("ds-popover", DsPopover);
338
+
339
+ declare global {
340
+ interface HTMLElementTagNameMap {
341
+ "ds-popover": DsPopover;
342
+ }
343
+ }
@@ -0,0 +1,117 @@
1
+ "use client";
2
+
3
+ import { type HTMLAttributes, createElement, forwardRef } from "react";
4
+ import "@hypoth-ui/wc";
5
+ import {
6
+ type ResponsiveProp,
7
+ generateResponsiveDataAttr,
8
+ isResponsiveObject,
9
+ resolveResponsiveValue,
10
+ } from "../../primitives/responsive.js";
11
+
12
+ export type ProgressVariant = "linear" | "circular";
13
+ export type ProgressSize = "sm" | "md" | "lg";
14
+
15
+ export interface ProgressProps extends Omit<HTMLAttributes<HTMLElement>, "children"> {
16
+ /**
17
+ * Current progress value (0-100). Omit for indeterminate.
18
+ */
19
+ value?: number;
20
+
21
+ /**
22
+ * Maximum value.
23
+ * @default 100
24
+ */
25
+ max?: number;
26
+
27
+ /**
28
+ * Visual variant.
29
+ * @default "linear"
30
+ */
31
+ variant?: ProgressVariant;
32
+
33
+ /**
34
+ * Size variant - supports responsive object syntax.
35
+ * @default "md"
36
+ * @example
37
+ * ```tsx
38
+ * // Single value
39
+ * <Progress value={75} size="md" />
40
+ *
41
+ * // Responsive
42
+ * <Progress value={75} size={{ base: "sm", md: "lg" }} />
43
+ * ```
44
+ */
45
+ size?: ResponsiveProp<ProgressSize>;
46
+
47
+ /**
48
+ * Accessible label.
49
+ */
50
+ label?: string;
51
+
52
+ /**
53
+ * Show value as percentage text (circular only).
54
+ * @default false
55
+ */
56
+ showValue?: boolean;
57
+ }
58
+
59
+ /**
60
+ * Progress indicator component for showing loading or completion status.
61
+ *
62
+ * @example
63
+ * ```tsx
64
+ * // Determinate linear progress
65
+ * <Progress value={75} label="Uploading..." />
66
+ *
67
+ * // Indeterminate circular progress
68
+ * <Progress variant="circular" label="Loading" />
69
+ *
70
+ * // Circular with percentage display
71
+ * <Progress variant="circular" value={45} showValue />
72
+ * ```
73
+ */
74
+ export const Progress = forwardRef<HTMLElement, ProgressProps>(function Progress(
75
+ {
76
+ value,
77
+ max = 100,
78
+ variant = "linear",
79
+ size = "md",
80
+ label,
81
+ showValue = false,
82
+ className,
83
+ ...props
84
+ },
85
+ ref
86
+ ) {
87
+ // Resolve responsive size - use base value for the WC attribute
88
+ const resolvedSize = resolveResponsiveValue(size, "md");
89
+ const isResponsive = isResponsiveObject(size);
90
+ const responsiveSizeAttr = isResponsive ? generateResponsiveDataAttr(size) : undefined;
91
+
92
+ return createElement("ds-progress", {
93
+ ref,
94
+ value,
95
+ max,
96
+ variant,
97
+ size: resolvedSize,
98
+ label,
99
+ "show-value": showValue || undefined,
100
+ class: className,
101
+ // Add responsive data attribute for CSS targeting
102
+ "data-size-responsive": responsiveSizeAttr,
103
+ ...props,
104
+ });
105
+ });
106
+
107
+ // TypeScript declaration for JSX
108
+ declare global {
109
+ namespace JSX {
110
+ interface IntrinsicElements {
111
+ "ds-progress": ProgressProps & {
112
+ ref?: React.Ref<HTMLElement>;
113
+ "show-value"?: boolean;
114
+ };
115
+ }
116
+ }
117
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Progress component exports
3
+ */
4
+ export { DsProgress, type ProgressVariant, type ProgressSize } from "./progress.js";
@@ -0,0 +1,174 @@
1
+ import { type TemplateResult, html, nothing } from "lit";
2
+ import { property } from "lit/decorators.js";
3
+ import { classMap } from "lit/directives/class-map.js";
4
+ import { DSElement } from "../../base/ds-element.js";
5
+ import { define } from "../../registry/define.js";
6
+
7
+ export type ProgressVariant = "linear" | "circular";
8
+ export type ProgressSize = "sm" | "md" | "lg";
9
+
10
+ /**
11
+ * Progress indicator component.
12
+ *
13
+ * @element ds-progress
14
+ *
15
+ * @csspart track - The progress track
16
+ * @csspart bar - The progress bar/fill
17
+ * @csspart label - The accessible label
18
+ *
19
+ * @cssprop --ds-progress-track - Track background color
20
+ * @cssprop --ds-progress-fill - Fill/indicator color
21
+ * @cssprop --ds-progress-height - Track height (linear)
22
+ */
23
+ export class DsProgress extends DSElement {
24
+ static override styles = [];
25
+
26
+ /**
27
+ * Current progress value (0-100). Omit for indeterminate.
28
+ */
29
+ @property({ type: Number })
30
+ value?: number;
31
+
32
+ /**
33
+ * Maximum value.
34
+ */
35
+ @property({ type: Number })
36
+ max = 100;
37
+
38
+ /**
39
+ * Visual variant.
40
+ */
41
+ @property({ type: String, reflect: true })
42
+ variant: ProgressVariant = "linear";
43
+
44
+ /**
45
+ * Size variant.
46
+ */
47
+ @property({ type: String, reflect: true })
48
+ size: ProgressSize = "md";
49
+
50
+ /**
51
+ * Accessible label.
52
+ */
53
+ @property({ type: String })
54
+ label = "";
55
+
56
+ /**
57
+ * Show value as percentage text (circular only).
58
+ */
59
+ @property({ type: Boolean, attribute: "show-value" })
60
+ showValue = false;
61
+
62
+ private get isIndeterminate(): boolean {
63
+ return this.value === undefined || this.value === null;
64
+ }
65
+
66
+ private get percentage(): number {
67
+ if (this.isIndeterminate) return 0;
68
+ return Math.min(100, Math.max(0, ((this.value ?? 0) / this.max) * 100));
69
+ }
70
+
71
+ private get valueText(): string {
72
+ if (this.isIndeterminate) {
73
+ return this.label || "Loading...";
74
+ }
75
+ return `${Math.round(this.percentage)}% complete`;
76
+ }
77
+
78
+ private renderLinear(): TemplateResult {
79
+ const classes = {
80
+ "ds-progress": true,
81
+ };
82
+
83
+ return html`
84
+ <div
85
+ part="track"
86
+ class=${classMap(classes)}
87
+ role="progressbar"
88
+ aria-valuenow=${this.isIndeterminate ? nothing : this.value}
89
+ aria-valuemin="0"
90
+ aria-valuemax=${this.max}
91
+ aria-valuetext=${this.valueText}
92
+ aria-label=${this.label || nothing}
93
+ ?aria-busy=${this.isIndeterminate}
94
+ data-size=${this.size}
95
+ ?data-indeterminate=${this.isIndeterminate}
96
+ >
97
+ <div
98
+ part="bar"
99
+ class="ds-progress__bar"
100
+ style=${this.isIndeterminate ? "" : `width: ${this.percentage}%`}
101
+ ></div>
102
+ ${
103
+ this.label
104
+ ? html`<span part="label" class="ds-progress__label">${this.label}</span>`
105
+ : nothing
106
+ }
107
+ </div>
108
+ `;
109
+ }
110
+
111
+ private renderCircular(): TemplateResult {
112
+ // SVG circle calculations
113
+ const size = this.size === "sm" ? 24 : this.size === "lg" ? 64 : 40;
114
+ const strokeWidth = this.size === "sm" ? 3 : this.size === "lg" ? 6 : 4;
115
+ const radius = (size - strokeWidth) / 2;
116
+ const circumference = 2 * Math.PI * radius;
117
+ const offset = circumference - (this.percentage / 100) * circumference;
118
+
119
+ const classes = {
120
+ "ds-progress-circular": true,
121
+ };
122
+
123
+ return html`
124
+ <div
125
+ class=${classMap(classes)}
126
+ role="progressbar"
127
+ aria-valuenow=${this.isIndeterminate ? nothing : this.value}
128
+ aria-valuemin="0"
129
+ aria-valuemax=${this.max}
130
+ aria-valuetext=${this.valueText}
131
+ aria-label=${this.label || nothing}
132
+ ?aria-busy=${this.isIndeterminate}
133
+ data-size=${this.size}
134
+ ?data-indeterminate=${this.isIndeterminate}
135
+ >
136
+ <svg class="ds-progress-circular__svg" viewBox="0 0 ${size} ${size}">
137
+ <circle
138
+ class="ds-progress-circular__track"
139
+ cx=${size / 2}
140
+ cy=${size / 2}
141
+ r=${radius}
142
+ />
143
+ <circle
144
+ class="ds-progress-circular__fill"
145
+ cx=${size / 2}
146
+ cy=${size / 2}
147
+ r=${radius}
148
+ stroke-dasharray=${circumference}
149
+ stroke-dashoffset=${this.isIndeterminate ? 0 : offset}
150
+ />
151
+ </svg>
152
+ ${
153
+ this.showValue && !this.isIndeterminate
154
+ ? html`<span class="ds-progress-circular__label">${Math.round(this.percentage)}%</span>`
155
+ : nothing
156
+ }
157
+ </div>
158
+ `;
159
+ }
160
+
161
+ override render(): TemplateResult {
162
+ return this.variant === "circular" ? this.renderCircular() : this.renderLinear();
163
+ }
164
+ }
165
+
166
+ // Register the component
167
+ define("ds-progress", DsProgress);
168
+
169
+ // TypeScript declaration for HTML
170
+ declare global {
171
+ interface HTMLElementTagNameMap {
172
+ "ds-progress": DsProgress;
173
+ }
174
+ }
@@ -0,0 +1,43 @@
1
+ import type React from "react";
2
+ import { type HTMLAttributes, createElement, forwardRef, useEffect, useRef } from "react";
3
+
4
+ export interface RadioProps extends HTMLAttributes<HTMLElement> {
5
+ /** Radio value */
6
+ value: string;
7
+ /** Whether disabled */
8
+ disabled?: boolean;
9
+ /** Radio label content */
10
+ children?: React.ReactNode;
11
+ }
12
+
13
+ /**
14
+ * React wrapper for ds-radio Web Component.
15
+ * Individual radio option within a RadioGroup.
16
+ */
17
+ export const Radio = forwardRef<HTMLElement, RadioProps>((props, forwardedRef) => {
18
+ const { value, disabled = false, children, className, ...rest } = props;
19
+
20
+ const internalRef = useRef<HTMLElement>(null);
21
+
22
+ useEffect(() => {
23
+ if (typeof forwardedRef === "function") {
24
+ forwardedRef(internalRef.current);
25
+ } else if (forwardedRef) {
26
+ (forwardedRef as React.MutableRefObject<HTMLElement | null>).current = internalRef.current;
27
+ }
28
+ }, [forwardedRef]);
29
+
30
+ return createElement(
31
+ "ds-radio",
32
+ {
33
+ ref: internalRef,
34
+ value,
35
+ disabled: disabled || undefined,
36
+ class: className,
37
+ ...rest,
38
+ },
39
+ children
40
+ );
41
+ });
42
+
43
+ Radio.displayName = "Radio";