@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,90 @@
1
+ import type React from "react";
2
+ import {
3
+ type HTMLAttributes,
4
+ createElement,
5
+ forwardRef,
6
+ useCallback,
7
+ useEffect,
8
+ useRef,
9
+ } from "react";
10
+
11
+ export interface SwitchProps extends Omit<HTMLAttributes<HTMLElement>, "onChange"> {
12
+ /** Switch name */
13
+ name?: string;
14
+ /** Whether checked/on */
15
+ checked?: boolean;
16
+ /** Default checked state (uncontrolled) */
17
+ defaultChecked?: boolean;
18
+ /** Whether disabled */
19
+ disabled?: boolean;
20
+ /** Whether required */
21
+ required?: boolean;
22
+ /** Change handler */
23
+ onChange?: (checked: boolean, event: Event) => void;
24
+ /** Switch label content */
25
+ children?: React.ReactNode;
26
+ }
27
+
28
+ /**
29
+ * React wrapper for ds-switch Web Component.
30
+ * Toggle switch with role="switch".
31
+ */
32
+ export const Switch = forwardRef<HTMLElement, SwitchProps>((props, forwardedRef) => {
33
+ const {
34
+ name,
35
+ checked,
36
+ defaultChecked,
37
+ disabled = false,
38
+ required = false,
39
+ onChange,
40
+ children,
41
+ className,
42
+ ...rest
43
+ } = props;
44
+
45
+ const internalRef = useRef<HTMLElement>(null);
46
+
47
+ // Store handler in ref for stable callback reference
48
+ const onChangeRef = useRef(onChange);
49
+ onChangeRef.current = onChange;
50
+
51
+ useEffect(() => {
52
+ if (typeof forwardedRef === "function") {
53
+ forwardedRef(internalRef.current);
54
+ } else if (forwardedRef) {
55
+ (forwardedRef as React.MutableRefObject<HTMLElement | null>).current = internalRef.current;
56
+ }
57
+ }, [forwardedRef]);
58
+
59
+ // Stable handler that reads from ref
60
+ const handleChange = useCallback((event: Event) => {
61
+ const customEvent = event as CustomEvent<{ checked: boolean }>;
62
+ onChangeRef.current?.(customEvent.detail.checked, event);
63
+ }, []);
64
+
65
+ // Handle change events - no handler deps needed
66
+ useEffect(() => {
67
+ const element = internalRef.current;
68
+ if (!element) return;
69
+
70
+ element.addEventListener("ds:change", handleChange);
71
+ return () => element.removeEventListener("ds:change", handleChange);
72
+ }, [handleChange]);
73
+
74
+ return createElement(
75
+ "ds-switch",
76
+ {
77
+ ref: internalRef,
78
+ name,
79
+ checked: checked || undefined,
80
+ "default-checked": defaultChecked || undefined,
81
+ disabled: disabled || undefined,
82
+ required: required || undefined,
83
+ class: className,
84
+ ...rest,
85
+ },
86
+ children
87
+ );
88
+ });
89
+
90
+ Switch.displayName = "Switch";
@@ -0,0 +1,228 @@
1
+ import { html } from "lit";
2
+ import type { PropertyValues } from "lit";
3
+ import { property, state } from "lit/decorators.js";
4
+ import { ifDefined } from "lit/directives/if-defined.js";
5
+ import { DSElement } from "../../base/ds-element.js";
6
+ import { FormAssociatedMixin } from "../../base/form-associated.js";
7
+ import type { ValidationFlags } from "../../base/form-associated.js";
8
+ import { StandardEvents, emitEvent } from "../../events/emit.js";
9
+ import { define } from "../../registry/define.js";
10
+
11
+ /**
12
+ * Toggle switch for boolean settings with role="switch" semantics and native form participation.
13
+ *
14
+ * Uses ElementInternals for form association - values are submitted with the form
15
+ * and the switch participates in constraint validation.
16
+ *
17
+ * @element ds-switch
18
+ * @fires ds:change - Fired on state change with { checked }
19
+ * @fires ds:invalid - Fired when customValidation is true and validation fails
20
+ *
21
+ * @slot - Switch label
22
+ *
23
+ * @example
24
+ * ```html
25
+ * <form>
26
+ * <ds-switch name="notifications">Enable notifications</ds-switch>
27
+ * <button type="submit">Submit</button>
28
+ * </form>
29
+ *
30
+ * <ds-field>
31
+ * <ds-label>Dark Mode</ds-label>
32
+ * <ds-switch name="darkMode" custom-validation>Enable dark mode</ds-switch>
33
+ * <ds-field-description>Switch between light and dark themes</ds-field-description>
34
+ * <ds-field-error></ds-field-error>
35
+ * </ds-field>
36
+ * ```
37
+ */
38
+ export class DsSwitch extends FormAssociatedMixin(DSElement) {
39
+ /** Checked (on) state */
40
+ @property({ type: Boolean, reflect: true })
41
+ checked = false;
42
+
43
+ /** ARIA describedby - IDs of elements that describe this switch */
44
+ @state()
45
+ private ariaDescribedBy?: string;
46
+
47
+ /** Label text captured from slot */
48
+ @state()
49
+ private labelText = "";
50
+
51
+ /** Unique ID for label association */
52
+ @state()
53
+ private labelId = "";
54
+
55
+ /** Default checked state for form reset */
56
+ private _defaultChecked = false;
57
+
58
+ private attributeObserver: MutationObserver | null = null;
59
+
60
+ override connectedCallback(): void {
61
+ // Capture label text before Lit renders
62
+ this.labelText = this.textContent?.trim() ?? "";
63
+ // Generate unique ID for label
64
+ this.labelId = `switch-label-${crypto.randomUUID().slice(0, 8)}`;
65
+ // Store default checked state
66
+ this._defaultChecked = this.checked;
67
+
68
+ super.connectedCallback();
69
+
70
+ // Set default value for form association
71
+ if (!this.value) {
72
+ this.value = "on";
73
+ }
74
+
75
+ // Observe ARIA attribute changes on the host element
76
+ this.attributeObserver = new MutationObserver((mutations) => {
77
+ for (const mutation of mutations) {
78
+ if (mutation.type === "attributes") {
79
+ this.syncAriaAttributes();
80
+ }
81
+ }
82
+ });
83
+
84
+ this.attributeObserver.observe(this, {
85
+ attributes: true,
86
+ attributeFilter: ["aria-describedby", "aria-invalid", "aria-required", "aria-disabled"],
87
+ });
88
+
89
+ // Initial sync
90
+ this.syncAriaAttributes();
91
+ }
92
+
93
+ override disconnectedCallback(): void {
94
+ super.disconnectedCallback();
95
+ this.attributeObserver?.disconnect();
96
+ this.attributeObserver = null;
97
+ }
98
+
99
+ /**
100
+ * Syncs ARIA attributes from the host element to internal state.
101
+ */
102
+ private syncAriaAttributes(): void {
103
+ this.ariaDescribedBy = this.getAttribute("aria-describedby") ?? undefined;
104
+
105
+ // Sync required state from aria-required
106
+ const ariaRequired = this.getAttribute("aria-required");
107
+ if (ariaRequired === "true") {
108
+ this.required = true;
109
+ }
110
+
111
+ // Sync disabled state from aria-disabled
112
+ const ariaDisabled = this.getAttribute("aria-disabled");
113
+ if (ariaDisabled === "true") {
114
+ this.disabled = true;
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Toggles the switch state.
120
+ */
121
+ private toggle(): void {
122
+ if (this.disabled) return;
123
+
124
+ this.checked = !this.checked;
125
+
126
+ emitEvent(this, StandardEvents.CHANGE, {
127
+ detail: {
128
+ checked: this.checked,
129
+ },
130
+ });
131
+ }
132
+
133
+ private handleClick = (event: Event): void => {
134
+ event.preventDefault();
135
+ this.toggle();
136
+ };
137
+
138
+ private handleKeyDown = (event: KeyboardEvent): void => {
139
+ // Both Space and Enter keys toggle the switch (distinct from checkbox)
140
+ if ((event.key === " " || event.key === "Enter") && !this.disabled) {
141
+ event.preventDefault();
142
+ this.toggle();
143
+ }
144
+ };
145
+
146
+ // Form association implementation
147
+
148
+ protected getFormValue(): string | null {
149
+ return this.checked ? this.value : null;
150
+ }
151
+
152
+ protected getValidationAnchor(): HTMLElement | undefined {
153
+ return this.querySelector(".ds-switch__control") as HTMLElement | undefined;
154
+ }
155
+
156
+ protected getValidationFlags(): ValidationFlags {
157
+ if (this.required && !this.checked) {
158
+ return { valueMissing: true };
159
+ }
160
+ return {};
161
+ }
162
+
163
+ protected getValidationMessage(flags: ValidationFlags): string {
164
+ if (flags.valueMissing) {
165
+ return "Please turn this switch on to proceed";
166
+ }
167
+ return "";
168
+ }
169
+
170
+ protected shouldUpdateFormValue(changedProperties: PropertyValues): boolean {
171
+ return changedProperties.has("checked");
172
+ }
173
+
174
+ protected shouldUpdateValidity(changedProperties: PropertyValues): boolean {
175
+ return changedProperties.has("checked");
176
+ }
177
+
178
+ protected onFormReset(): void {
179
+ this.checked = this._defaultChecked;
180
+ }
181
+
182
+ protected onFormStateRestore(
183
+ state: string | File | FormData | null,
184
+ _mode: "restore" | "autocomplete"
185
+ ): void {
186
+ if (typeof state === "string") {
187
+ this.checked = state === this.value;
188
+ }
189
+ }
190
+
191
+ override render() {
192
+ return html`
193
+ <div
194
+ class="ds-switch"
195
+ part="container"
196
+ @click=${this.handleClick}
197
+ >
198
+ <div
199
+ role="switch"
200
+ part="control"
201
+ class="ds-switch__control"
202
+ tabindex=${this.disabled ? -1 : 0}
203
+ aria-checked=${this.checked ? "true" : "false"}
204
+ aria-disabled=${this.disabled ? "true" : "false"}
205
+ aria-required=${this.required ? "true" : "false"}
206
+ aria-labelledby=${this.labelId}
207
+ aria-describedby=${ifDefined(this.ariaDescribedBy)}
208
+ @keydown=${this.handleKeyDown}
209
+ >
210
+ <span class="ds-switch__track" part="track">
211
+ <span class="ds-switch__thumb" part="thumb"></span>
212
+ </span>
213
+ </div>
214
+ <span id=${this.labelId} class="ds-switch__label" part="label">
215
+ ${this.labelText}
216
+ </span>
217
+ </div>
218
+ `;
219
+ }
220
+ }
221
+
222
+ define("ds-switch", DsSwitch);
223
+
224
+ declare global {
225
+ interface HTMLElementTagNameMap {
226
+ "ds-switch": DsSwitch;
227
+ }
228
+ }
@@ -0,0 +1,21 @@
1
+ "use client";
2
+
3
+ import { type HTMLAttributes, type ReactNode, createElement, forwardRef } from "react";
4
+ import "@hypoth-ui/wc";
5
+
6
+ export interface TableBodyProps extends HTMLAttributes<HTMLElement> {
7
+ /**
8
+ * Table body rows.
9
+ */
10
+ children?: ReactNode;
11
+ }
12
+
13
+ /**
14
+ * Table body component (tbody).
15
+ */
16
+ export const TableBody = forwardRef<HTMLElement, TableBodyProps>(function TableBody(
17
+ { children, className, ...props },
18
+ ref
19
+ ) {
20
+ return createElement("ds-table-body", { ref, class: className, ...props }, children);
21
+ });
@@ -0,0 +1,44 @@
1
+ "use client";
2
+
3
+ import { type HTMLAttributes, type ReactNode, createElement, forwardRef } from "react";
4
+ import "@hypoth-ui/wc";
5
+ import type { TableAlign } from "./head.js";
6
+
7
+ export interface TableCellProps extends HTMLAttributes<HTMLElement> {
8
+ /**
9
+ * Text alignment.
10
+ * @default "left"
11
+ */
12
+ align?: TableAlign;
13
+
14
+ /**
15
+ * Column span.
16
+ * @default 1
17
+ */
18
+ colSpan?: number;
19
+
20
+ /**
21
+ * Row span.
22
+ * @default 1
23
+ */
24
+ rowSpan?: number;
25
+
26
+ /**
27
+ * Cell content.
28
+ */
29
+ children?: ReactNode;
30
+ }
31
+
32
+ /**
33
+ * Table cell component (td).
34
+ */
35
+ export const TableCell = forwardRef<HTMLElement, TableCellProps>(function TableCell(
36
+ { align = "left", colSpan = 1, rowSpan = 1, children, className, ...props },
37
+ ref
38
+ ) {
39
+ return createElement(
40
+ "ds-table-cell",
41
+ { ref, align, colspan: colSpan, rowspan: rowSpan, class: className, ...props },
42
+ children
43
+ );
44
+ });
@@ -0,0 +1,112 @@
1
+ "use client";
2
+
3
+ import {
4
+ type HTMLAttributes,
5
+ type ReactNode,
6
+ createElement,
7
+ forwardRef,
8
+ useEffect,
9
+ useRef,
10
+ } from "react";
11
+ import "@hypoth-ui/wc";
12
+
13
+ export type TableAlign = "left" | "center" | "right";
14
+ export type SortDirection = "asc" | "desc" | "none";
15
+
16
+ export interface TableHeadProps extends HTMLAttributes<HTMLElement> {
17
+ /**
18
+ * Column key for sorting.
19
+ */
20
+ column?: string;
21
+
22
+ /**
23
+ * Text alignment.
24
+ * @default "left"
25
+ */
26
+ align?: TableAlign;
27
+
28
+ /**
29
+ * Whether this column is sortable.
30
+ * @default false
31
+ */
32
+ sortable?: boolean;
33
+
34
+ /**
35
+ * Current sort direction.
36
+ * @default "none"
37
+ */
38
+ sortDirection?: SortDirection;
39
+
40
+ /**
41
+ * Column width (CSS value).
42
+ */
43
+ width?: string;
44
+
45
+ /**
46
+ * Callback when sort is triggered.
47
+ */
48
+ onSort?: (column: string, direction: SortDirection) => void;
49
+
50
+ /**
51
+ * Header cell content.
52
+ */
53
+ children?: ReactNode;
54
+ }
55
+
56
+ /**
57
+ * Table header cell component (th).
58
+ */
59
+ export const TableHead = forwardRef<HTMLElement, TableHeadProps>(function TableHead(
60
+ {
61
+ column,
62
+ align = "left",
63
+ sortable = false,
64
+ sortDirection = "none",
65
+ width,
66
+ onSort,
67
+ children,
68
+ className,
69
+ ...props
70
+ },
71
+ forwardedRef
72
+ ) {
73
+ const internalRef = useRef<HTMLElement>(null);
74
+
75
+ // Sync forwarded ref
76
+ useEffect(() => {
77
+ if (typeof forwardedRef === "function") {
78
+ forwardedRef(internalRef.current);
79
+ } else if (forwardedRef) {
80
+ (forwardedRef as React.MutableRefObject<HTMLElement | null>).current = internalRef.current;
81
+ }
82
+ }, [forwardedRef]);
83
+
84
+ // Set up event listeners
85
+ useEffect(() => {
86
+ const element = internalRef.current;
87
+ if (!element) return;
88
+
89
+ const handleSort = (e: Event) => {
90
+ const event = e as CustomEvent<{ column: string; direction: SortDirection }>;
91
+ onSort?.(event.detail.column, event.detail.direction);
92
+ };
93
+
94
+ element.addEventListener("ds:sort", handleSort);
95
+ return () => element.removeEventListener("ds:sort", handleSort);
96
+ }, [onSort]);
97
+
98
+ return createElement(
99
+ "ds-table-head",
100
+ {
101
+ ref: internalRef,
102
+ column,
103
+ align,
104
+ sortable: sortable || undefined,
105
+ "sort-direction": sortDirection,
106
+ width,
107
+ class: className,
108
+ ...props,
109
+ },
110
+ children
111
+ );
112
+ });
@@ -0,0 +1,21 @@
1
+ "use client";
2
+
3
+ import { type HTMLAttributes, type ReactNode, createElement, forwardRef } from "react";
4
+ import "@hypoth-ui/wc";
5
+
6
+ export interface TableHeaderProps extends HTMLAttributes<HTMLElement> {
7
+ /**
8
+ * Table header rows.
9
+ */
10
+ children?: ReactNode;
11
+ }
12
+
13
+ /**
14
+ * Table header component (thead).
15
+ */
16
+ export const TableHeader = forwardRef<HTMLElement, TableHeaderProps>(function TableHeader(
17
+ { children, className, ...props },
18
+ ref
19
+ ) {
20
+ return createElement("ds-table-header", { ref, class: className, ...props }, children);
21
+ });
@@ -0,0 +1,93 @@
1
+ "use client";
2
+
3
+ /**
4
+ * Table compound component exports
5
+ */
6
+
7
+ import { TableBody } from "./body.js";
8
+ import { TableCell } from "./cell.js";
9
+ import { TableHead } from "./head.js";
10
+ import { TableHeader } from "./header.js";
11
+ import { TableRoot } from "./root.js";
12
+ import { TableRow } from "./row.js";
13
+
14
+ export type { TableRootProps, TableSize } from "./root.js";
15
+ export type { TableHeaderProps } from "./header.js";
16
+ export type { TableBodyProps } from "./body.js";
17
+ export type { TableRowProps } from "./row.js";
18
+ export type { TableHeadProps, TableAlign, SortDirection } from "./head.js";
19
+ export type { TableCellProps } from "./cell.js";
20
+
21
+ /**
22
+ * Table compound component for structured data display.
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * <Table striped>
27
+ * <Table.Header>
28
+ * <Table.Row>
29
+ * <Table.Head sortable column="name" onSort={handleSort}>Name</Table.Head>
30
+ * <Table.Head>Email</Table.Head>
31
+ * </Table.Row>
32
+ * </Table.Header>
33
+ * <Table.Body>
34
+ * <Table.Row>
35
+ * <Table.Cell>John Doe</Table.Cell>
36
+ * <Table.Cell>john@example.com</Table.Cell>
37
+ * </Table.Row>
38
+ * </Table.Body>
39
+ * </Table>
40
+ * ```
41
+ */
42
+ export const Table = Object.assign(TableRoot, {
43
+ Header: TableHeader,
44
+ Body: TableBody,
45
+ Row: TableRow,
46
+ Head: TableHead,
47
+ Cell: TableCell,
48
+ });
49
+
50
+ export { TableHeader, TableBody, TableRow, TableHead, TableCell };
51
+
52
+ // TypeScript declarations for JSX
53
+ declare global {
54
+ namespace JSX {
55
+ interface IntrinsicElements {
56
+ "ds-table": React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {
57
+ ref?: React.Ref<HTMLElement>;
58
+ size?: string;
59
+ striped?: boolean;
60
+ borderless?: boolean;
61
+ fixed?: boolean;
62
+ "sticky-header"?: boolean;
63
+ caption?: string;
64
+ };
65
+ "ds-table-header": React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {
66
+ ref?: React.Ref<HTMLElement>;
67
+ };
68
+ "ds-table-body": React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {
69
+ ref?: React.Ref<HTMLElement>;
70
+ };
71
+ "ds-table-row": React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {
72
+ ref?: React.Ref<HTMLElement>;
73
+ "row-id"?: string;
74
+ selected?: boolean;
75
+ };
76
+ "ds-table-head": React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {
77
+ ref?: React.Ref<HTMLElement>;
78
+ column?: string;
79
+ align?: string;
80
+ sortable?: boolean;
81
+ "sort-direction"?: string;
82
+ width?: string;
83
+ "onDs-sort"?: (event: CustomEvent) => void;
84
+ };
85
+ "ds-table-cell": React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {
86
+ ref?: React.Ref<HTMLElement>;
87
+ align?: string;
88
+ colspan?: number;
89
+ rowspan?: number;
90
+ };
91
+ }
92
+ }
93
+ }
@@ -0,0 +1,82 @@
1
+ "use client";
2
+
3
+ import { type HTMLAttributes, type ReactNode, createElement, forwardRef } from "react";
4
+ import "@hypoth-ui/wc";
5
+
6
+ export type TableSize = "compact" | "default" | "spacious";
7
+
8
+ export interface TableRootProps extends HTMLAttributes<HTMLElement> {
9
+ /**
10
+ * Size variant.
11
+ * @default "default"
12
+ */
13
+ size?: TableSize;
14
+
15
+ /**
16
+ * Whether to show striped rows.
17
+ * @default false
18
+ */
19
+ striped?: boolean;
20
+
21
+ /**
22
+ * Whether to remove borders.
23
+ * @default false
24
+ */
25
+ borderless?: boolean;
26
+
27
+ /**
28
+ * Whether to use fixed layout.
29
+ * @default false
30
+ */
31
+ fixed?: boolean;
32
+
33
+ /**
34
+ * Whether header is sticky.
35
+ * @default false
36
+ */
37
+ stickyHeader?: boolean;
38
+
39
+ /**
40
+ * Accessible caption for screen readers.
41
+ */
42
+ caption?: string;
43
+
44
+ /**
45
+ * Table content.
46
+ */
47
+ children?: ReactNode;
48
+ }
49
+
50
+ /**
51
+ * Table root component.
52
+ */
53
+ export const TableRoot = forwardRef<HTMLElement, TableRootProps>(function TableRoot(
54
+ {
55
+ size = "default",
56
+ striped = false,
57
+ borderless = false,
58
+ fixed = false,
59
+ stickyHeader = false,
60
+ caption,
61
+ children,
62
+ className,
63
+ ...props
64
+ },
65
+ ref
66
+ ) {
67
+ return createElement(
68
+ "ds-table",
69
+ {
70
+ ref,
71
+ size,
72
+ striped: striped || undefined,
73
+ borderless: borderless || undefined,
74
+ fixed: fixed || undefined,
75
+ "sticky-header": stickyHeader || undefined,
76
+ caption,
77
+ class: className,
78
+ ...props,
79
+ },
80
+ children
81
+ );
82
+ });