@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,89 @@
1
+ "use client";
2
+
3
+ /**
4
+ * useToast Hook
5
+ *
6
+ * React hook for showing and managing toasts.
7
+ */
8
+
9
+ import { useCallback, useContext } from "react";
10
+ import { ToastContext } from "./provider.js";
11
+
12
+ export interface ToastOptions {
13
+ /** Toast title (required) */
14
+ title: string;
15
+ /** Optional description */
16
+ description?: string;
17
+ /** Visual variant */
18
+ variant?: "info" | "success" | "warning" | "error";
19
+ /** Auto-dismiss duration in ms (0 = no auto-dismiss) */
20
+ duration?: number;
21
+ /** Optional action button */
22
+ action?: {
23
+ label: string;
24
+ onClick: () => void;
25
+ };
26
+ }
27
+
28
+ export interface UseToastReturn {
29
+ /** Show a toast notification */
30
+ toast: (options: ToastOptions) => string;
31
+ /** Dismiss a specific toast */
32
+ dismiss: (id: string) => void;
33
+ /** Dismiss all toasts */
34
+ dismissAll: () => void;
35
+ }
36
+
37
+ /**
38
+ * Hook for showing toast notifications.
39
+ *
40
+ * @example
41
+ * ```tsx
42
+ * function MyComponent() {
43
+ * const { toast, dismiss } = useToast();
44
+ *
45
+ * const handleSave = async () => {
46
+ * try {
47
+ * await saveData();
48
+ * toast({ title: "Saved!", variant: "success" });
49
+ * } catch {
50
+ * toast({
51
+ * title: "Error",
52
+ * description: "Failed to save",
53
+ * variant: "error",
54
+ * action: { label: "Retry", onClick: handleSave },
55
+ * });
56
+ * }
57
+ * };
58
+ *
59
+ * return <button onClick={handleSave}>Save</button>;
60
+ * }
61
+ * ```
62
+ */
63
+ export function useToast(): UseToastReturn {
64
+ const context = useContext(ToastContext);
65
+
66
+ if (!context) {
67
+ throw new Error("useToast must be used within a Toast.Provider");
68
+ }
69
+
70
+ const toast = useCallback(
71
+ (options: ToastOptions): string => {
72
+ return context.show(options);
73
+ },
74
+ [context]
75
+ );
76
+
77
+ const dismiss = useCallback(
78
+ (id: string): void => {
79
+ context.dismiss(id);
80
+ },
81
+ [context]
82
+ );
83
+
84
+ const dismissAll = useCallback((): void => {
85
+ context.dismissAll();
86
+ }, [context]);
87
+
88
+ return { toast, dismiss, dismissAll };
89
+ }
@@ -0,0 +1,15 @@
1
+ export { DsToast } from "./toast.js";
2
+ export { DsToastProvider } from "./toast-provider.js";
3
+ export {
4
+ ToastController,
5
+ dsToast,
6
+ getGlobalToastController,
7
+ setGlobalToastController,
8
+ type ToastOptions,
9
+ type ToastData,
10
+ type ToastVariant,
11
+ type ToastPosition,
12
+ type ToastState,
13
+ type ToastAction,
14
+ type ToastControllerOptions,
15
+ } from "./toast-controller.js";
@@ -0,0 +1,282 @@
1
+ /**
2
+ * Toast Controller
3
+ *
4
+ * Manages toast queue, lifecycle, and provides imperative API
5
+ * for showing and dismissing toasts.
6
+ */
7
+
8
+ export type ToastVariant = "info" | "success" | "warning" | "error";
9
+ export type ToastPosition =
10
+ | "top-left"
11
+ | "top-center"
12
+ | "top-right"
13
+ | "bottom-left"
14
+ | "bottom-center"
15
+ | "bottom-right";
16
+
17
+ export type ToastState = "entering" | "visible" | "exiting" | "dismissed";
18
+
19
+ export interface ToastAction {
20
+ label: string;
21
+ onClick: () => void;
22
+ }
23
+
24
+ export interface ToastOptions {
25
+ /** Toast title (required) */
26
+ title: string;
27
+ /** Optional description */
28
+ description?: string;
29
+ /** Visual variant */
30
+ variant?: ToastVariant;
31
+ /** Auto-dismiss duration in ms (0 = no auto-dismiss) */
32
+ duration?: number;
33
+ /** Optional action button */
34
+ action?: ToastAction;
35
+ }
36
+
37
+ export interface ToastData extends ToastOptions {
38
+ /** Unique toast ID */
39
+ id: string;
40
+ /** Current lifecycle state */
41
+ state: ToastState;
42
+ /** Timestamp when created */
43
+ createdAt: number;
44
+ /** Timer ID for auto-dismiss */
45
+ timerId?: ReturnType<typeof setTimeout>;
46
+ }
47
+
48
+ export interface ToastControllerOptions {
49
+ /** Maximum simultaneous toasts */
50
+ maxToasts?: number;
51
+ /** Default duration in ms */
52
+ defaultDuration?: number;
53
+ /** Toast position */
54
+ position?: ToastPosition;
55
+ /** Callback when toast list changes */
56
+ onUpdate?: (toasts: ToastData[]) => void;
57
+ }
58
+
59
+ let toastIdCounter = 0;
60
+
61
+ function generateId(): string {
62
+ return `toast-${++toastIdCounter}-${Date.now()}`;
63
+ }
64
+
65
+ /**
66
+ * ToastController manages the toast queue and lifecycle.
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * const controller = new ToastController({
71
+ * maxToasts: 5,
72
+ * defaultDuration: 5000,
73
+ * onUpdate: (toasts) => renderToasts(toasts),
74
+ * });
75
+ *
76
+ * // Show a toast
77
+ * const id = controller.show({ title: "Saved!", variant: "success" });
78
+ *
79
+ * // Dismiss a specific toast
80
+ * controller.dismiss(id);
81
+ *
82
+ * // Dismiss all toasts
83
+ * controller.dismissAll();
84
+ * ```
85
+ */
86
+ export class ToastController {
87
+ private toasts: ToastData[] = [];
88
+ private options: Required<ToastControllerOptions>;
89
+
90
+ constructor(options: ToastControllerOptions = {}) {
91
+ this.options = {
92
+ maxToasts: options.maxToasts ?? 5,
93
+ defaultDuration: options.defaultDuration ?? 5000,
94
+ position: options.position ?? "top-right",
95
+ onUpdate: options.onUpdate ?? (() => {}),
96
+ };
97
+ }
98
+
99
+ /**
100
+ * Show a new toast
101
+ */
102
+ show(options: ToastOptions): string {
103
+ const id = generateId();
104
+ const duration = options.duration ?? this.options.defaultDuration;
105
+
106
+ const toast: ToastData = {
107
+ id,
108
+ title: options.title,
109
+ description: options.description,
110
+ variant: options.variant ?? "info",
111
+ duration,
112
+ action: options.action,
113
+ state: "entering",
114
+ createdAt: Date.now(),
115
+ };
116
+
117
+ // Add to queue
118
+ this.toasts = [toast, ...this.toasts];
119
+
120
+ // Trim to max
121
+ if (this.toasts.length > this.options.maxToasts) {
122
+ const toRemove = this.toasts.slice(this.options.maxToasts);
123
+ for (const t of toRemove) {
124
+ this.dismiss(t.id);
125
+ }
126
+ this.toasts = this.toasts.slice(0, this.options.maxToasts);
127
+ }
128
+
129
+ // Transition to visible after animation
130
+ setTimeout(() => {
131
+ this.updateState(id, "visible");
132
+ }, 200);
133
+
134
+ // Set up auto-dismiss
135
+ if (duration > 0) {
136
+ toast.timerId = setTimeout(() => {
137
+ this.dismiss(id);
138
+ }, duration);
139
+ }
140
+
141
+ this.notify();
142
+ return id;
143
+ }
144
+
145
+ /**
146
+ * Dismiss a toast by ID
147
+ */
148
+ dismiss(id: string): void {
149
+ const toast = this.toasts.find((t) => t.id === id);
150
+ if (!toast || toast.state === "exiting" || toast.state === "dismissed") {
151
+ return;
152
+ }
153
+
154
+ // Clear auto-dismiss timer
155
+ if (toast.timerId) {
156
+ clearTimeout(toast.timerId);
157
+ }
158
+
159
+ // Start exit animation
160
+ this.updateState(id, "exiting");
161
+
162
+ // Remove after animation
163
+ setTimeout(() => {
164
+ this.toasts = this.toasts.filter((t) => t.id !== id);
165
+ this.notify();
166
+ }, 150);
167
+ }
168
+
169
+ /**
170
+ * Dismiss all toasts
171
+ */
172
+ dismissAll(): void {
173
+ const ids = this.toasts.map((t) => t.id);
174
+ for (const id of ids) {
175
+ this.dismiss(id);
176
+ }
177
+ }
178
+
179
+ /**
180
+ * Pause auto-dismiss for a toast (e.g., on hover)
181
+ */
182
+ pause(id: string): void {
183
+ const toast = this.toasts.find((t) => t.id === id);
184
+ if (toast?.timerId) {
185
+ clearTimeout(toast.timerId);
186
+ toast.timerId = undefined;
187
+ }
188
+ }
189
+
190
+ /**
191
+ * Resume auto-dismiss for a toast
192
+ */
193
+ resume(id: string): void {
194
+ const toast = this.toasts.find((t) => t.id === id);
195
+ if (toast?.duration && toast.duration > 0 && toast.state === "visible") {
196
+ // Calculate remaining time based on elapsed time
197
+ const elapsed = Date.now() - toast.createdAt;
198
+ const remaining = Math.max(toast.duration - elapsed, 1000);
199
+
200
+ toast.timerId = setTimeout(() => {
201
+ this.dismiss(id);
202
+ }, remaining);
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Get current toasts
208
+ */
209
+ getToasts(): ToastData[] {
210
+ return [...this.toasts];
211
+ }
212
+
213
+ /**
214
+ * Get controller options
215
+ */
216
+ getOptions(): Required<ToastControllerOptions> {
217
+ return { ...this.options };
218
+ }
219
+
220
+ /**
221
+ * Update controller options
222
+ */
223
+ setOptions(options: Partial<ToastControllerOptions>): void {
224
+ this.options = { ...this.options, ...options };
225
+ }
226
+
227
+ private updateState(id: string, state: ToastState): void {
228
+ const toast = this.toasts.find((t) => t.id === id);
229
+ if (toast) {
230
+ toast.state = state;
231
+ this.notify();
232
+ }
233
+ }
234
+
235
+ private notify(): void {
236
+ this.options.onUpdate(this.getToasts());
237
+ }
238
+ }
239
+
240
+ // Global singleton controller
241
+ let globalController: ToastController | null = null;
242
+
243
+ /**
244
+ * Get or create the global toast controller
245
+ */
246
+ export function getGlobalToastController(): ToastController {
247
+ if (!globalController) {
248
+ globalController = new ToastController();
249
+ }
250
+ return globalController;
251
+ }
252
+
253
+ /**
254
+ * Set the global toast controller (used by ToastProvider)
255
+ */
256
+ export function setGlobalToastController(controller: ToastController): void {
257
+ globalController = controller;
258
+ }
259
+
260
+ /**
261
+ * Global toast function for showing toasts
262
+ *
263
+ * @example
264
+ * ```typescript
265
+ * dsToast({ title: "Saved!", variant: "success" });
266
+ *
267
+ * dsToast({
268
+ * title: "Error",
269
+ * description: "Something went wrong",
270
+ * variant: "error",
271
+ * action: { label: "Retry", onClick: () => retry() },
272
+ * });
273
+ * ```
274
+ */
275
+ export function dsToast(options: ToastOptions): string {
276
+ return getGlobalToastController().show(options);
277
+ }
278
+
279
+ // Make dsToast available globally
280
+ if (typeof window !== "undefined") {
281
+ (window as unknown as { dsToast: typeof dsToast }).dsToast = dsToast;
282
+ }
@@ -0,0 +1,161 @@
1
+ import { type TemplateResult, html } from "lit";
2
+ import { property, state } from "lit/decorators.js";
3
+ import { repeat } from "lit/directives/repeat.js";
4
+ import { DSElement } from "../../base/ds-element.js";
5
+ import { define } from "../../registry/define.js";
6
+ import {
7
+ ToastController,
8
+ type ToastData,
9
+ type ToastPosition,
10
+ setGlobalToastController,
11
+ } from "./toast-controller.js";
12
+ import "./toast.js";
13
+
14
+ /**
15
+ * Toast provider component that manages toast queue and rendering.
16
+ *
17
+ * @element ds-toast-provider
18
+ * @slot - Default slot for app content
19
+ *
20
+ * @example
21
+ * ```html
22
+ * <ds-toast-provider position="top-right" max="5">
23
+ * <!-- Your app content -->
24
+ * </ds-toast-provider>
25
+ *
26
+ * <script>
27
+ * dsToast({ title: "Hello!", variant: "success" });
28
+ * </script>
29
+ * ```
30
+ */
31
+ export class DsToastProvider extends DSElement {
32
+ static override styles = [];
33
+
34
+ /**
35
+ * Toast position
36
+ */
37
+ @property({ type: String, reflect: true })
38
+ position: ToastPosition = "top-right";
39
+
40
+ /**
41
+ * Maximum simultaneous toasts
42
+ */
43
+ @property({ type: Number })
44
+ max = 5;
45
+
46
+ /**
47
+ * Default duration in ms
48
+ */
49
+ @property({ type: Number })
50
+ duration = 5000;
51
+
52
+ @state()
53
+ private toasts: ToastData[] = [];
54
+
55
+ private controller!: ToastController;
56
+
57
+ override connectedCallback(): void {
58
+ super.connectedCallback();
59
+
60
+ this.controller = new ToastController({
61
+ maxToasts: this.max,
62
+ defaultDuration: this.duration,
63
+ position: this.position,
64
+ onUpdate: (toasts) => {
65
+ this.toasts = toasts;
66
+ },
67
+ });
68
+
69
+ // Set as global controller
70
+ setGlobalToastController(this.controller);
71
+ }
72
+
73
+ override updated(changedProperties: Map<string, unknown>): void {
74
+ super.updated(changedProperties);
75
+
76
+ if (
77
+ changedProperties.has("max") ||
78
+ changedProperties.has("duration") ||
79
+ changedProperties.has("position")
80
+ ) {
81
+ this.controller.setOptions({
82
+ maxToasts: this.max,
83
+ defaultDuration: this.duration,
84
+ position: this.position,
85
+ });
86
+ }
87
+ }
88
+
89
+ private handleDismiss(event: CustomEvent<{ id: string }>): void {
90
+ this.controller.dismiss(event.detail.id);
91
+ }
92
+
93
+ private handlePause(event: CustomEvent<{ id: string }>): void {
94
+ this.controller.pause(event.detail.id);
95
+ }
96
+
97
+ private handleResume(event: CustomEvent<{ id: string }>): void {
98
+ this.controller.resume(event.detail.id);
99
+ }
100
+
101
+ private handleActionClick(toast: ToastData): void {
102
+ toast.action?.onClick();
103
+ this.controller.dismiss(toast.id);
104
+ }
105
+
106
+ override render(): TemplateResult {
107
+ return html`
108
+ <slot></slot>
109
+
110
+ <div
111
+ class="ds-toast-viewport"
112
+ data-position=${this.position}
113
+ role="region"
114
+ aria-label="Notifications"
115
+ aria-live="polite"
116
+ >
117
+ ${repeat(
118
+ this.toasts,
119
+ (toast) => toast.id,
120
+ (toast) => html`
121
+ <ds-toast
122
+ .toastId=${toast.id}
123
+ .toastTitle=${toast.title}
124
+ .description=${toast.description ?? ""}
125
+ .variant=${toast.variant ?? "info"}
126
+ .toastState=${toast.state}
127
+ .duration=${toast.duration ?? 0}
128
+ @ds:dismiss=${this.handleDismiss}
129
+ @ds:pause=${this.handlePause}
130
+ @ds:resume=${this.handleResume}
131
+ >
132
+ ${
133
+ toast.action
134
+ ? html`
135
+ <button
136
+ slot="action"
137
+ class="ds-button ds-button--sm ds-button--ghost"
138
+ @click=${() => this.handleActionClick(toast)}
139
+ >
140
+ ${toast.action.label}
141
+ </button>
142
+ `
143
+ : null
144
+ }
145
+ </ds-toast>
146
+ `
147
+ )}
148
+ </div>
149
+ `;
150
+ }
151
+ }
152
+
153
+ // Register the component
154
+ define("ds-toast-provider", DsToastProvider);
155
+
156
+ // TypeScript declaration for HTML
157
+ declare global {
158
+ interface HTMLElementTagNameMap {
159
+ "ds-toast-provider": DsToastProvider;
160
+ }
161
+ }
@@ -0,0 +1,165 @@
1
+ import { type TemplateResult, html, nothing } from "lit";
2
+ import { property, state } from "lit/decorators.js";
3
+ import { classMap } from "lit/directives/class-map.js";
4
+ import { DSElement } from "../../base/ds-element.js";
5
+ import { emitEvent } from "../../events/emit.js";
6
+ import { define } from "../../registry/define.js";
7
+ import type { ToastState, ToastVariant } from "./toast-controller.js";
8
+
9
+ /**
10
+ * SVG icons for different toast variants
11
+ */
12
+ const VARIANT_ICONS: Record<ToastVariant, TemplateResult> = {
13
+ info: html`<svg class="ds-toast__icon" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
14
+ <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z" clip-rule="evenodd" />
15
+ </svg>`,
16
+ success: html`<svg class="ds-toast__icon" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
17
+ <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z" clip-rule="evenodd" />
18
+ </svg>`,
19
+ warning: html`<svg class="ds-toast__icon" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
20
+ <path fill-rule="evenodd" d="M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd" />
21
+ </svg>`,
22
+ error: html`<svg class="ds-toast__icon" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
23
+ <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z" clip-rule="evenodd" />
24
+ </svg>`,
25
+ };
26
+
27
+ const CLOSE_ICON = html`<svg class="ds-toast__close-icon" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
28
+ <path d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" />
29
+ </svg>`;
30
+
31
+ /**
32
+ * Individual toast notification element.
33
+ *
34
+ * @element ds-toast
35
+ * @slot action - Action button slot
36
+ *
37
+ * @fires ds:dismiss - Fired when toast is dismissed
38
+ * @fires ds:pause - Fired when mouse enters (for pause)
39
+ * @fires ds:resume - Fired when mouse leaves (for resume)
40
+ */
41
+ export class DsToast extends DSElement {
42
+ static override styles = [];
43
+
44
+ /**
45
+ * Unique toast ID
46
+ */
47
+ @property({ type: String, reflect: true })
48
+ toastId = "";
49
+
50
+ /**
51
+ * Toast title
52
+ */
53
+ @property({ type: String })
54
+ toastTitle = "";
55
+
56
+ /**
57
+ * Toast description
58
+ */
59
+ @property({ type: String })
60
+ description = "";
61
+
62
+ /**
63
+ * Visual variant
64
+ */
65
+ @property({ type: String, reflect: true })
66
+ variant: ToastVariant = "info";
67
+
68
+ /**
69
+ * Current state
70
+ */
71
+ @property({ type: String, reflect: true })
72
+ toastState: ToastState = "entering";
73
+
74
+ /**
75
+ * Duration for progress bar (0 = no progress)
76
+ */
77
+ @property({ type: Number })
78
+ duration = 5000;
79
+
80
+ /**
81
+ * Hide the icon
82
+ */
83
+ @property({ type: Boolean, attribute: "hide-icon" })
84
+ hideIcon = false;
85
+
86
+ @state()
87
+ private isPaused = false;
88
+
89
+ private handleDismiss(): void {
90
+ emitEvent(this, "dismiss", { detail: { id: this.toastId } });
91
+ }
92
+
93
+ private handleMouseEnter(): void {
94
+ this.isPaused = true;
95
+ emitEvent(this, "pause", { detail: { id: this.toastId } });
96
+ }
97
+
98
+ private handleMouseLeave(): void {
99
+ this.isPaused = false;
100
+ emitEvent(this, "resume", { detail: { id: this.toastId } });
101
+ }
102
+
103
+ override render(): TemplateResult {
104
+ const classes = {
105
+ "ds-toast": true,
106
+ };
107
+
108
+ return html`
109
+ <div
110
+ class=${classMap(classes)}
111
+ role="status"
112
+ aria-live="polite"
113
+ aria-atomic="true"
114
+ data-variant=${this.variant}
115
+ data-state=${this.toastState}
116
+ @mouseenter=${this.handleMouseEnter}
117
+ @mouseleave=${this.handleMouseLeave}
118
+ >
119
+ ${!this.hideIcon ? VARIANT_ICONS[this.variant] : nothing}
120
+
121
+ <div class="ds-toast__content">
122
+ <p class="ds-toast__title">${this.toastTitle}</p>
123
+ ${
124
+ this.description
125
+ ? html`<p class="ds-toast__description">${this.description}</p>`
126
+ : nothing
127
+ }
128
+ <slot name="action" class="ds-toast__action"></slot>
129
+ </div>
130
+
131
+ <button
132
+ class="ds-toast__close"
133
+ type="button"
134
+ aria-label="Dismiss notification"
135
+ @click=${this.handleDismiss}
136
+ >
137
+ ${CLOSE_ICON}
138
+ </button>
139
+
140
+ ${
141
+ this.duration > 0
142
+ ? html`
143
+ <div class="ds-toast__progress">
144
+ <div
145
+ class="ds-toast__progress-bar"
146
+ style="animation: ds-toast-progress ${this.duration}ms linear forwards; animation-play-state: ${this.isPaused ? "paused" : "running"}"
147
+ ></div>
148
+ </div>
149
+ `
150
+ : nothing
151
+ }
152
+ </div>
153
+ `;
154
+ }
155
+ }
156
+
157
+ // Register the component
158
+ define("ds-toast", DsToast);
159
+
160
+ // TypeScript declaration for HTML
161
+ declare global {
162
+ interface HTMLElementTagNameMap {
163
+ "ds-toast": DsToast;
164
+ }
165
+ }