@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,280 @@
1
+ import { html } from "lit";
2
+ import { property, state } from "lit/decorators.js";
3
+ import { ifDefined } from "lit/directives/if-defined.js";
4
+ import { DSElement } from "../../base/ds-element.js";
5
+ import { StandardEvents, emitEvent } from "../../events/emit.js";
6
+ import { define } from "../../registry/define.js";
7
+ import { devWarn, hasAccessibleLabel, Warnings } from "../../utils/dev-warnings.js";
8
+
9
+ export type TextareaSize = "sm" | "md" | "lg";
10
+
11
+ /**
12
+ * A textarea component with optional auto-resize.
13
+ *
14
+ * @element ds-textarea
15
+ * @fires input - Fired when the textarea value changes
16
+ * @fires ds:change - Fired when the textarea value is committed
17
+ *
18
+ * @example
19
+ * ```html
20
+ * <ds-field>
21
+ * <ds-label>Description</ds-label>
22
+ * <ds-textarea placeholder="Enter description..."></ds-textarea>
23
+ * </ds-field>
24
+ * ```
25
+ */
26
+ export class DsTextarea extends DSElement {
27
+ /** Textarea size */
28
+ @property({ type: String, reflect: true })
29
+ size: TextareaSize = "md";
30
+
31
+ /** Textarea name */
32
+ @property({ type: String, reflect: true })
33
+ name = "";
34
+
35
+ /** Textarea value */
36
+ @property({ type: String })
37
+ value = "";
38
+
39
+ /** Placeholder text */
40
+ @property({ type: String })
41
+ placeholder = "";
42
+
43
+ /** Disabled state */
44
+ @property({ type: Boolean, reflect: true })
45
+ disabled = false;
46
+
47
+ /** Read-only state */
48
+ @property({ type: Boolean, reflect: true })
49
+ readonly = false;
50
+
51
+ /** Required state */
52
+ @property({ type: Boolean, reflect: true })
53
+ required = false;
54
+
55
+ /** Error state */
56
+ @property({ type: Boolean, reflect: true })
57
+ error = false;
58
+
59
+ /** Minimum length */
60
+ @property({ type: Number })
61
+ minlength?: number;
62
+
63
+ /** Maximum length */
64
+ @property({ type: Number })
65
+ maxlength?: number;
66
+
67
+ /** Number of visible text rows */
68
+ @property({ type: Number })
69
+ rows = 3;
70
+
71
+ /** Minimum number of rows (for auto-resize) */
72
+ @property({ type: Number })
73
+ minRows = 3;
74
+
75
+ /** Maximum number of rows (for auto-resize) */
76
+ @property({ type: Number })
77
+ maxRows?: number;
78
+
79
+ /** Enable auto-resize behavior */
80
+ @property({ type: Boolean })
81
+ autoResize = true;
82
+
83
+ /** ARIA labelledby - ID of element that labels this textarea */
84
+ @state()
85
+ private ariaLabelledBy?: string;
86
+
87
+ /** ARIA describedby - IDs of elements that describe this textarea */
88
+ @state()
89
+ private ariaDescribedBy?: string;
90
+
91
+ private attributeObserver: MutationObserver | null = null;
92
+ private nativeTextarea: HTMLTextAreaElement | null = null;
93
+
94
+ override connectedCallback(): void {
95
+ super.connectedCallback();
96
+
97
+ // Observe ARIA attribute changes on the host element
98
+ this.attributeObserver = new MutationObserver((mutations) => {
99
+ for (const mutation of mutations) {
100
+ if (mutation.type === "attributes") {
101
+ this.syncAriaAttributes();
102
+ }
103
+ }
104
+ });
105
+
106
+ this.attributeObserver.observe(this, {
107
+ attributes: true,
108
+ attributeFilter: [
109
+ "aria-labelledby",
110
+ "aria-describedby",
111
+ "aria-invalid",
112
+ "aria-required",
113
+ "aria-disabled",
114
+ ],
115
+ });
116
+
117
+ // Initial sync
118
+ this.syncAriaAttributes();
119
+
120
+ // Dev warning: Check for accessible label after DOM is ready
121
+ requestAnimationFrame(() => {
122
+ if (!hasAccessibleLabel(this)) {
123
+ const field = this.closest("ds-field");
124
+ const hasFieldLabel = field?.querySelector("ds-label") !== null;
125
+ if (!hasFieldLabel) {
126
+ devWarn(Warnings.inputMissingLabel("ds-textarea"));
127
+ }
128
+ }
129
+ });
130
+ }
131
+
132
+ override disconnectedCallback(): void {
133
+ super.disconnectedCallback();
134
+ this.attributeObserver?.disconnect();
135
+ this.attributeObserver = null;
136
+ }
137
+
138
+ /**
139
+ * Syncs ARIA attributes from the host element to internal state.
140
+ * The render method will apply these to the native textarea.
141
+ */
142
+ private syncAriaAttributes(): void {
143
+ this.ariaLabelledBy = this.getAttribute("aria-labelledby") ?? undefined;
144
+ this.ariaDescribedBy = this.getAttribute("aria-describedby") ?? undefined;
145
+
146
+ // Sync error state from aria-invalid
147
+ const ariaInvalid = this.getAttribute("aria-invalid");
148
+ if (ariaInvalid === "true") {
149
+ this.error = true;
150
+ } else if (ariaInvalid === "false") {
151
+ this.error = false;
152
+ }
153
+
154
+ // Sync required state from aria-required
155
+ const ariaRequired = this.getAttribute("aria-required");
156
+ if (ariaRequired === "true") {
157
+ this.required = true;
158
+ }
159
+
160
+ // Sync disabled state from aria-disabled
161
+ const ariaDisabled = this.getAttribute("aria-disabled");
162
+ if (ariaDisabled === "true") {
163
+ this.disabled = true;
164
+ }
165
+ }
166
+
167
+ private handleInput(event: Event) {
168
+ const textarea = event.target as HTMLTextAreaElement;
169
+ this.value = textarea.value;
170
+
171
+ // Auto-resize if enabled
172
+ if (this.autoResize) {
173
+ this.adjustHeight(textarea);
174
+ }
175
+
176
+ // Also emit native input event for compatibility
177
+ this.dispatchEvent(
178
+ new CustomEvent("input", {
179
+ detail: { value: this.value },
180
+ bubbles: true,
181
+ composed: true,
182
+ })
183
+ );
184
+ }
185
+
186
+ private handleChange(event: Event) {
187
+ const textarea = event.target as HTMLTextAreaElement;
188
+ this.value = textarea.value;
189
+ // Emit ds:change event using standard convention
190
+ emitEvent(this, StandardEvents.CHANGE, {
191
+ detail: { value: this.value },
192
+ });
193
+ }
194
+
195
+ /**
196
+ * Adjusts the textarea height based on content.
197
+ */
198
+ private adjustHeight(textarea: HTMLTextAreaElement): void {
199
+ // Reset height to calculate scrollHeight
200
+ textarea.style.height = "auto";
201
+
202
+ // Calculate line height from computed styles
203
+ const computedStyle = getComputedStyle(textarea);
204
+ const lineHeight = Number.parseFloat(computedStyle.lineHeight) || 20;
205
+ const paddingTop = Number.parseFloat(computedStyle.paddingTop) || 0;
206
+ const paddingBottom = Number.parseFloat(computedStyle.paddingBottom) || 0;
207
+ const borderTop = Number.parseFloat(computedStyle.borderTopWidth) || 0;
208
+ const borderBottom = Number.parseFloat(computedStyle.borderBottomWidth) || 0;
209
+
210
+ // Calculate min and max heights based on rows
211
+ const minHeight =
212
+ this.minRows * lineHeight + paddingTop + paddingBottom + borderTop + borderBottom;
213
+ const maxHeight = this.maxRows
214
+ ? this.maxRows * lineHeight + paddingTop + paddingBottom + borderTop + borderBottom
215
+ : Number.POSITIVE_INFINITY;
216
+
217
+ // Set height within bounds
218
+ const scrollHeight = textarea.scrollHeight;
219
+ const newHeight = Math.min(Math.max(scrollHeight, minHeight), maxHeight);
220
+ textarea.style.height = `${newHeight}px`;
221
+
222
+ // Enable scrolling if maxRows is set and content exceeds it
223
+ textarea.style.overflowY = scrollHeight > maxHeight ? "auto" : "hidden";
224
+ }
225
+
226
+ override updated(changedProperties: Map<string, unknown>): void {
227
+ super.updated(changedProperties);
228
+
229
+ // Get reference to native textarea
230
+ if (!this.nativeTextarea) {
231
+ this.nativeTextarea = this.querySelector("textarea");
232
+ }
233
+
234
+ // Adjust height when value changes and auto-resize is enabled
235
+ if (changedProperties.has("value") && this.autoResize && this.nativeTextarea) {
236
+ this.adjustHeight(this.nativeTextarea);
237
+ }
238
+ }
239
+
240
+ /**
241
+ * Returns the effective number of rows.
242
+ */
243
+ private getEffectiveRows(): number {
244
+ return Math.max(this.rows, this.minRows);
245
+ }
246
+
247
+ override render() {
248
+ return html`
249
+ <div class="ds-textarea" part="container" data-size=${this.size}>
250
+ <textarea
251
+ part="textarea"
252
+ class="ds-textarea__field"
253
+ name=${this.name}
254
+ .value=${this.value}
255
+ placeholder=${this.placeholder}
256
+ .rows=${this.getEffectiveRows()}
257
+ ?disabled=${this.disabled}
258
+ ?readonly=${this.readonly}
259
+ ?required=${this.required}
260
+ aria-invalid=${this.error ? "true" : "false"}
261
+ aria-labelledby=${ifDefined(this.ariaLabelledBy)}
262
+ aria-describedby=${ifDefined(this.ariaDescribedBy)}
263
+ aria-required=${this.required ? "true" : "false"}
264
+ minlength=${ifDefined(this.minlength)}
265
+ maxlength=${ifDefined(this.maxlength)}
266
+ @input=${this.handleInput}
267
+ @change=${this.handleChange}
268
+ ></textarea>
269
+ </div>
270
+ `;
271
+ }
272
+ }
273
+
274
+ define("ds-textarea", DsTextarea);
275
+
276
+ declare global {
277
+ interface HTMLElementTagNameMap {
278
+ "ds-textarea": DsTextarea;
279
+ }
280
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * TimePicker compound component for time selection.
3
+ *
4
+ * @example
5
+ * ```tsx
6
+ * // Basic 12-hour format
7
+ * <TimePicker.Root hourFormat={12} onValueChange={(time) => console.log(time)}>
8
+ * <TimePicker.Segment segment="hour" />
9
+ * <span>:</span>
10
+ * <TimePicker.Segment segment="minute" />
11
+ * <span> </span>
12
+ * <TimePicker.Segment segment="period" />
13
+ * </TimePicker.Root>
14
+ *
15
+ * // 24-hour format with seconds
16
+ * <TimePicker.Root hourFormat={24} showSeconds>
17
+ * <TimePicker.Segment segment="hour" />
18
+ * <span>:</span>
19
+ * <TimePicker.Segment segment="minute" />
20
+ * <span>:</span>
21
+ * <TimePicker.Segment segment="second" />
22
+ * </TimePicker.Root>
23
+ * ```
24
+ */
25
+
26
+ export { TimePickerRoot, type TimePickerRootProps } from "./time-picker-root.js";
27
+ export { TimePickerSegment, type TimePickerSegmentProps } from "./time-picker-segment.js";
28
+ export {
29
+ useTimePickerContext,
30
+ type TimePickerContextValue,
31
+ } from "./time-picker-context.js";
32
+
33
+ // Re-export types from primitives
34
+ export type { TimeValue, TimeSegment } from "@hypoth-ui/primitives-dom";
35
+
36
+ export const TimePicker = {
37
+ Root: TimePickerRoot,
38
+ Segment: TimePickerSegment,
39
+ } as const;
40
+
41
+ import { TimePickerRoot } from "./time-picker-root.js";
42
+ import { TimePickerSegment } from "./time-picker-segment.js";
@@ -0,0 +1,28 @@
1
+ /**
2
+ * TimePicker context for compound component pattern.
3
+ */
4
+
5
+ import type { TimePickerBehavior, TimeSegment, TimeValue } from "@hypoth-ui/primitives-dom";
6
+ import { createCompoundContext } from "../../utils/create-context.js";
7
+
8
+ export interface TimePickerContextValue {
9
+ /** TimePicker behavior instance */
10
+ behavior: TimePickerBehavior;
11
+ /** Current time value */
12
+ value: TimeValue;
13
+ /** Set value */
14
+ setValue: (value: TimeValue) => void;
15
+ /** Hour format */
16
+ hourFormat: 12 | 24;
17
+ /** Show seconds */
18
+ showSeconds: boolean;
19
+ /** Focused segment */
20
+ focusedSegment: TimeSegment | null;
21
+ /** Set focused segment */
22
+ setFocusedSegment: (segment: TimeSegment | null) => void;
23
+ /** Disabled state */
24
+ disabled: boolean;
25
+ }
26
+
27
+ export const [TimePickerProvider, useTimePickerContext] =
28
+ createCompoundContext<TimePickerContextValue>("TimePicker");
@@ -0,0 +1,113 @@
1
+ /**
2
+ * TimePicker Root component - provides context to all TimePicker compound components.
3
+ */
4
+
5
+ import { type TimeSegment, type TimeValue, createTimePickerBehavior } from "@hypoth-ui/primitives-dom";
6
+ import { type ReactNode, useCallback, useMemo, useState } from "react";
7
+ import { TimePickerProvider } from "./time-picker-context.js";
8
+
9
+ export interface TimePickerRootProps {
10
+ /** TimePicker content */
11
+ children?: ReactNode;
12
+ /** 12-hour or 24-hour format */
13
+ hourFormat?: 12 | 24;
14
+ /** Show seconds segment */
15
+ showSeconds?: boolean;
16
+ /** Controlled time value */
17
+ value?: TimeValue;
18
+ /** Default time value (uncontrolled) */
19
+ defaultValue?: TimeValue;
20
+ /** Called when time changes */
21
+ onValueChange?: (value: TimeValue) => void;
22
+ /** Minute step */
23
+ minuteStep?: number;
24
+ /** Second step */
25
+ secondStep?: number;
26
+ /** Minimum time */
27
+ minTime?: TimeValue;
28
+ /** Maximum time */
29
+ maxTime?: TimeValue;
30
+ /** Disabled state */
31
+ disabled?: boolean;
32
+ }
33
+
34
+ /**
35
+ * Root component for TimePicker compound pattern.
36
+ * Provides context to Segment components.
37
+ *
38
+ * @example
39
+ * ```tsx
40
+ * <TimePicker.Root hourFormat={12} onValueChange={(time) => console.log(time)}>
41
+ * <TimePicker.Segment segment="hour" />
42
+ * <span>:</span>
43
+ * <TimePicker.Segment segment="minute" />
44
+ * <TimePicker.Segment segment="period" />
45
+ * </TimePicker.Root>
46
+ * ```
47
+ */
48
+ export function TimePickerRoot({
49
+ children,
50
+ hourFormat = 12,
51
+ showSeconds = false,
52
+ value: controlledValue,
53
+ defaultValue = { hour: 0, minute: 0, second: 0 },
54
+ onValueChange,
55
+ minuteStep = 1,
56
+ secondStep = 1,
57
+ minTime,
58
+ maxTime,
59
+ disabled = false,
60
+ }: TimePickerRootProps) {
61
+ // Support controlled and uncontrolled modes
62
+ const [internalValue, setInternalValue] = useState<TimeValue>(defaultValue);
63
+ const isControlled = controlledValue !== undefined;
64
+ const value = isControlled ? controlledValue : internalValue;
65
+
66
+ const [focusedSegment, setFocusedSegment] = useState<TimeSegment | null>(null);
67
+
68
+ const setValue = useCallback(
69
+ (nextValue: TimeValue) => {
70
+ if (!isControlled) {
71
+ setInternalValue(nextValue);
72
+ }
73
+ onValueChange?.(nextValue);
74
+ },
75
+ [isControlled, onValueChange]
76
+ );
77
+
78
+ // Create behavior instance
79
+ // biome-ignore lint/correctness/useExhaustiveDependencies: behavior is created once
80
+ const behavior = useMemo(
81
+ () =>
82
+ createTimePickerBehavior({
83
+ defaultValue: value,
84
+ hourFormat,
85
+ showSeconds,
86
+ minuteStep,
87
+ secondStep,
88
+ minTime,
89
+ maxTime,
90
+ disabled,
91
+ onValueChange: setValue,
92
+ }),
93
+ []
94
+ );
95
+
96
+ const contextValue = useMemo(
97
+ () => ({
98
+ behavior,
99
+ value,
100
+ setValue,
101
+ hourFormat,
102
+ showSeconds,
103
+ focusedSegment,
104
+ setFocusedSegment,
105
+ disabled,
106
+ }),
107
+ [behavior, value, setValue, hourFormat, showSeconds, focusedSegment, disabled]
108
+ );
109
+
110
+ return <TimePickerProvider value={contextValue}>{children}</TimePickerProvider>;
111
+ }
112
+
113
+ TimePickerRoot.displayName = "TimePicker.Root";
@@ -0,0 +1,91 @@
1
+ /**
2
+ * TimePicker Segment component - individual time segment (hour, minute, second, period).
3
+ */
4
+
5
+ import type { TimeSegment } from "@hypoth-ui/primitives-dom";
6
+ import {
7
+ type FocusEvent,
8
+ type HTMLAttributes,
9
+ type KeyboardEvent,
10
+ forwardRef,
11
+ useCallback,
12
+ } from "react";
13
+ import { useTimePickerContext } from "./time-picker-context.js";
14
+
15
+ export interface TimePickerSegmentProps extends Omit<HTMLAttributes<HTMLSpanElement>, "children"> {
16
+ /** Which segment this represents */
17
+ segment: TimeSegment;
18
+ }
19
+
20
+ /**
21
+ * Individual segment for time input (hour, minute, second, or period).
22
+ *
23
+ * @example
24
+ * ```tsx
25
+ * <TimePicker.Segment segment="hour" />
26
+ * <span>:</span>
27
+ * <TimePicker.Segment segment="minute" />
28
+ * ```
29
+ */
30
+ export const TimePickerSegment = forwardRef<HTMLSpanElement, TimePickerSegmentProps>(
31
+ ({ segment, className, onFocus, onBlur, onKeyDown, ...restProps }, ref) => {
32
+ const { behavior, focusedSegment, setFocusedSegment, disabled } =
33
+ useTimePickerContext("TimePicker.Segment");
34
+
35
+ const props = behavior.getSegmentProps(segment);
36
+ const displayValue = behavior.getSegmentDisplayValue(segment);
37
+ const isFocused = focusedSegment === segment;
38
+
39
+ const handleFocus = useCallback(
40
+ (event: FocusEvent<HTMLSpanElement>) => {
41
+ setFocusedSegment(segment);
42
+ behavior.focusSegment(segment);
43
+ onFocus?.(event);
44
+ },
45
+ [behavior, segment, setFocusedSegment, onFocus]
46
+ );
47
+
48
+ const handleBlur = useCallback(
49
+ (event: FocusEvent<HTMLSpanElement>) => {
50
+ setFocusedSegment(null);
51
+ behavior.blur();
52
+ onBlur?.(event);
53
+ },
54
+ [behavior, setFocusedSegment, onBlur]
55
+ );
56
+
57
+ const handleKeyDown = useCallback(
58
+ (event: KeyboardEvent<HTMLSpanElement>) => {
59
+ behavior.handleSegmentKeyDown(segment, event.nativeEvent);
60
+ onKeyDown?.(event);
61
+ },
62
+ [behavior, segment, onKeyDown]
63
+ );
64
+
65
+ return (
66
+ <span
67
+ ref={ref}
68
+ role={props.role}
69
+ tabIndex={props.tabIndex}
70
+ aria-valuemin={props["aria-valuemin"]}
71
+ aria-valuemax={props["aria-valuemax"]}
72
+ aria-valuenow={props["aria-valuenow"]}
73
+ aria-valuetext={props["aria-valuetext"]}
74
+ aria-label={props["aria-label"]}
75
+ aria-disabled={props["aria-disabled"]}
76
+ className={className}
77
+ data-segment={segment}
78
+ data-focused={isFocused || undefined}
79
+ data-disabled={disabled || undefined}
80
+ onFocus={handleFocus}
81
+ onBlur={handleBlur}
82
+ onKeyDown={handleKeyDown}
83
+ {...restProps}
84
+ >
85
+ {displayValue}
86
+ </span>
87
+ );
88
+ }
89
+ );
90
+
91
+ TimePickerSegment.displayName = "TimePicker.Segment";
@@ -0,0 +1 @@
1
+ export { DsTimePicker } from "./time-picker.js";