@dowel-ui/react 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 (691) hide show
  1. package/LICENSE +21 -0
  2. package/dist/blocks/admin-users/meta.js +27 -0
  3. package/dist/blocks/admin-users/meta.js.map +1 -0
  4. package/dist/blocks/ai-chat/meta.js +30 -0
  5. package/dist/blocks/ai-chat/meta.js.map +1 -0
  6. package/dist/blocks/dashboard/meta.js +23 -0
  7. package/dist/blocks/dashboard/meta.js.map +1 -0
  8. package/dist/blocks/forgot-password/meta.js +24 -0
  9. package/dist/blocks/forgot-password/meta.js.map +1 -0
  10. package/dist/blocks/login/meta.js +26 -0
  11. package/dist/blocks/login/meta.js.map +1 -0
  12. package/dist/blocks/pricing/meta.js +24 -0
  13. package/dist/blocks/pricing/meta.js.map +1 -0
  14. package/dist/blocks/settings/meta.js +29 -0
  15. package/dist/blocks/settings/meta.js.map +1 -0
  16. package/dist/blocks/signup/meta.js +25 -0
  17. package/dist/blocks/signup/meta.js.map +1 -0
  18. package/dist/components/accordion/accordion.d.ts +19 -0
  19. package/dist/components/accordion/accordion.d.ts.map +1 -0
  20. package/dist/components/accordion/accordion.js +58 -0
  21. package/dist/components/accordion/accordion.js.map +1 -0
  22. package/dist/components/accordion/index.d.ts +2 -0
  23. package/dist/components/accordion/index.js +2 -0
  24. package/dist/components/accordion/meta.js +17 -0
  25. package/dist/components/accordion/meta.js.map +1 -0
  26. package/dist/components/activity-feed/activity-feed.d.ts +39 -0
  27. package/dist/components/activity-feed/activity-feed.d.ts.map +1 -0
  28. package/dist/components/activity-feed/activity-feed.js +77 -0
  29. package/dist/components/activity-feed/activity-feed.js.map +1 -0
  30. package/dist/components/activity-feed/index.d.ts +2 -0
  31. package/dist/components/activity-feed/index.js +2 -0
  32. package/dist/components/activity-feed/meta.js +17 -0
  33. package/dist/components/activity-feed/meta.js.map +1 -0
  34. package/dist/components/ai-agent-status/ai-agent-status.d.ts +30 -0
  35. package/dist/components/ai-agent-status/ai-agent-status.d.ts.map +1 -0
  36. package/dist/components/ai-agent-status/ai-agent-status.js +43 -0
  37. package/dist/components/ai-agent-status/ai-agent-status.js.map +1 -0
  38. package/dist/components/ai-agent-status/index.d.ts +2 -0
  39. package/dist/components/ai-agent-status/index.js +2 -0
  40. package/dist/components/ai-agent-status/meta.js +17 -0
  41. package/dist/components/ai-agent-status/meta.js.map +1 -0
  42. package/dist/components/ai-conversation/ai-conversation.d.ts +45 -0
  43. package/dist/components/ai-conversation/ai-conversation.d.ts.map +1 -0
  44. package/dist/components/ai-conversation/ai-conversation.js +138 -0
  45. package/dist/components/ai-conversation/ai-conversation.js.map +1 -0
  46. package/dist/components/ai-conversation/index.d.ts +2 -0
  47. package/dist/components/ai-conversation/index.js +2 -0
  48. package/dist/components/ai-conversation/meta.js +17 -0
  49. package/dist/components/ai-conversation/meta.js.map +1 -0
  50. package/dist/components/ai-message/ai-message.d.ts +56 -0
  51. package/dist/components/ai-message/ai-message.d.ts.map +1 -0
  52. package/dist/components/ai-message/ai-message.js +90 -0
  53. package/dist/components/ai-message/ai-message.js.map +1 -0
  54. package/dist/components/ai-message/index.d.ts +2 -0
  55. package/dist/components/ai-message/index.js +2 -0
  56. package/dist/components/ai-message/meta.js +17 -0
  57. package/dist/components/ai-message/meta.js.map +1 -0
  58. package/dist/components/ai-model-selector/ai-model-selector.d.ts +42 -0
  59. package/dist/components/ai-model-selector/ai-model-selector.d.ts.map +1 -0
  60. package/dist/components/ai-model-selector/ai-model-selector.js +48 -0
  61. package/dist/components/ai-model-selector/ai-model-selector.js.map +1 -0
  62. package/dist/components/ai-model-selector/index.d.ts +2 -0
  63. package/dist/components/ai-model-selector/index.js +2 -0
  64. package/dist/components/ai-model-selector/meta.js +17 -0
  65. package/dist/components/ai-model-selector/meta.js.map +1 -0
  66. package/dist/components/ai-prompt-input/ai-prompt-input.d.ts +61 -0
  67. package/dist/components/ai-prompt-input/ai-prompt-input.d.ts.map +1 -0
  68. package/dist/components/ai-prompt-input/ai-prompt-input.js +170 -0
  69. package/dist/components/ai-prompt-input/ai-prompt-input.js.map +1 -0
  70. package/dist/components/ai-prompt-input/index.d.ts +2 -0
  71. package/dist/components/ai-prompt-input/index.js +2 -0
  72. package/dist/components/ai-prompt-input/meta.js +17 -0
  73. package/dist/components/ai-prompt-input/meta.js.map +1 -0
  74. package/dist/components/ai-reasoning/ai-reasoning.d.ts +24 -0
  75. package/dist/components/ai-reasoning/ai-reasoning.d.ts.map +1 -0
  76. package/dist/components/ai-reasoning/ai-reasoning.js +64 -0
  77. package/dist/components/ai-reasoning/ai-reasoning.js.map +1 -0
  78. package/dist/components/ai-reasoning/index.d.ts +2 -0
  79. package/dist/components/ai-reasoning/index.js +2 -0
  80. package/dist/components/ai-reasoning/meta.js +17 -0
  81. package/dist/components/ai-reasoning/meta.js.map +1 -0
  82. package/dist/components/ai-response/ai-response.d.ts +36 -0
  83. package/dist/components/ai-response/ai-response.d.ts.map +1 -0
  84. package/dist/components/ai-response/ai-response.js +46 -0
  85. package/dist/components/ai-response/ai-response.js.map +1 -0
  86. package/dist/components/ai-response/index.d.ts +2 -0
  87. package/dist/components/ai-response/index.js +2 -0
  88. package/dist/components/ai-response/meta.js +17 -0
  89. package/dist/components/ai-response/meta.js.map +1 -0
  90. package/dist/components/ai-sources/ai-sources.d.ts +44 -0
  91. package/dist/components/ai-sources/ai-sources.d.ts.map +1 -0
  92. package/dist/components/ai-sources/ai-sources.js +112 -0
  93. package/dist/components/ai-sources/ai-sources.js.map +1 -0
  94. package/dist/components/ai-sources/index.d.ts +2 -0
  95. package/dist/components/ai-sources/index.js +2 -0
  96. package/dist/components/ai-sources/meta.js +17 -0
  97. package/dist/components/ai-sources/meta.js.map +1 -0
  98. package/dist/components/ai-token-usage/ai-token-usage.d.ts +34 -0
  99. package/dist/components/ai-token-usage/ai-token-usage.d.ts.map +1 -0
  100. package/dist/components/ai-token-usage/ai-token-usage.js +58 -0
  101. package/dist/components/ai-token-usage/ai-token-usage.js.map +1 -0
  102. package/dist/components/ai-token-usage/index.d.ts +2 -0
  103. package/dist/components/ai-token-usage/index.js +2 -0
  104. package/dist/components/ai-token-usage/meta.js +17 -0
  105. package/dist/components/ai-token-usage/meta.js.map +1 -0
  106. package/dist/components/ai-tool/ai-tool.d.ts +50 -0
  107. package/dist/components/ai-tool/ai-tool.d.ts.map +1 -0
  108. package/dist/components/ai-tool/ai-tool.js +129 -0
  109. package/dist/components/ai-tool/ai-tool.js.map +1 -0
  110. package/dist/components/ai-tool/index.d.ts +2 -0
  111. package/dist/components/ai-tool/index.js +2 -0
  112. package/dist/components/ai-tool/meta.js +17 -0
  113. package/dist/components/ai-tool/meta.js.map +1 -0
  114. package/dist/components/alert/alert.d.ts +32 -0
  115. package/dist/components/alert/alert.d.ts.map +1 -0
  116. package/dist/components/alert/alert.js +49 -0
  117. package/dist/components/alert/alert.js.map +1 -0
  118. package/dist/components/alert/index.d.ts +2 -0
  119. package/dist/components/alert/index.js +2 -0
  120. package/dist/components/alert/meta.js +17 -0
  121. package/dist/components/alert/meta.js.map +1 -0
  122. package/dist/components/avatar/avatar.d.ts +23 -0
  123. package/dist/components/avatar/avatar.d.ts.map +1 -0
  124. package/dist/components/avatar/avatar.js +44 -0
  125. package/dist/components/avatar/avatar.js.map +1 -0
  126. package/dist/components/avatar/index.d.ts +2 -0
  127. package/dist/components/avatar/index.js +2 -0
  128. package/dist/components/avatar/meta.js +17 -0
  129. package/dist/components/avatar/meta.js.map +1 -0
  130. package/dist/components/badge/badge.d.ts +20 -0
  131. package/dist/components/badge/badge.d.ts.map +1 -0
  132. package/dist/components/badge/badge.js +47 -0
  133. package/dist/components/badge/badge.js.map +1 -0
  134. package/dist/components/badge/index.d.ts +2 -0
  135. package/dist/components/badge/index.js +2 -0
  136. package/dist/components/badge/meta.js +17 -0
  137. package/dist/components/badge/meta.js.map +1 -0
  138. package/dist/components/button/button.d.ts +28 -0
  139. package/dist/components/button/button.d.ts.map +1 -0
  140. package/dist/components/button/button.js +77 -0
  141. package/dist/components/button/button.js.map +1 -0
  142. package/dist/components/button/index.d.ts +2 -0
  143. package/dist/components/button/index.js +2 -0
  144. package/dist/components/button/meta.js +17 -0
  145. package/dist/components/button/meta.js.map +1 -0
  146. package/dist/components/calendar/calendar.d.ts +16 -0
  147. package/dist/components/calendar/calendar.d.ts.map +1 -0
  148. package/dist/components/calendar/calendar.js +70 -0
  149. package/dist/components/calendar/calendar.js.map +1 -0
  150. package/dist/components/calendar/index.d.ts +2 -0
  151. package/dist/components/calendar/index.js +2 -0
  152. package/dist/components/calendar/meta.js +17 -0
  153. package/dist/components/calendar/meta.js.map +1 -0
  154. package/dist/components/card/card.d.ts +23 -0
  155. package/dist/components/card/card.d.ts.map +1 -0
  156. package/dist/components/card/card.js +53 -0
  157. package/dist/components/card/card.js.map +1 -0
  158. package/dist/components/card/index.d.ts +2 -0
  159. package/dist/components/card/index.js +2 -0
  160. package/dist/components/card/meta.js +17 -0
  161. package/dist/components/card/meta.js.map +1 -0
  162. package/dist/components/checkbox/checkbox.d.ts +15 -0
  163. package/dist/components/checkbox/checkbox.d.ts.map +1 -0
  164. package/dist/components/checkbox/checkbox.js +45 -0
  165. package/dist/components/checkbox/checkbox.js.map +1 -0
  166. package/dist/components/checkbox/index.d.ts +2 -0
  167. package/dist/components/checkbox/index.js +2 -0
  168. package/dist/components/checkbox/meta.js +17 -0
  169. package/dist/components/checkbox/meta.js.map +1 -0
  170. package/dist/components/code-block/code-block.d.ts +46 -0
  171. package/dist/components/code-block/code-block.d.ts.map +1 -0
  172. package/dist/components/code-block/code-block.js +110 -0
  173. package/dist/components/code-block/code-block.js.map +1 -0
  174. package/dist/components/code-block/index.d.ts +2 -0
  175. package/dist/components/code-block/index.js +2 -0
  176. package/dist/components/code-block/meta.js +17 -0
  177. package/dist/components/code-block/meta.js.map +1 -0
  178. package/dist/components/combobox/combobox.d.ts +59 -0
  179. package/dist/components/combobox/combobox.d.ts.map +1 -0
  180. package/dist/components/combobox/combobox.js +346 -0
  181. package/dist/components/combobox/combobox.js.map +1 -0
  182. package/dist/components/combobox/index.d.ts +2 -0
  183. package/dist/components/combobox/index.js +2 -0
  184. package/dist/components/combobox/meta.js +17 -0
  185. package/dist/components/combobox/meta.js.map +1 -0
  186. package/dist/components/command/command.d.ts +65 -0
  187. package/dist/components/command/command.d.ts.map +1 -0
  188. package/dist/components/command/command.js +330 -0
  189. package/dist/components/command/command.js.map +1 -0
  190. package/dist/components/command/index.d.ts +2 -0
  191. package/dist/components/command/index.js +2 -0
  192. package/dist/components/command/meta.js +17 -0
  193. package/dist/components/command/meta.js.map +1 -0
  194. package/dist/components/data-table/data-table.d.ts +91 -0
  195. package/dist/components/data-table/data-table.d.ts.map +1 -0
  196. package/dist/components/data-table/data-table.js +263 -0
  197. package/dist/components/data-table/data-table.js.map +1 -0
  198. package/dist/components/data-table/index.d.ts +2 -0
  199. package/dist/components/data-table/index.js +2 -0
  200. package/dist/components/data-table/meta.js +22 -0
  201. package/dist/components/data-table/meta.js.map +1 -0
  202. package/dist/components/date-picker/date-picker.d.ts +31 -0
  203. package/dist/components/date-picker/date-picker.d.ts.map +1 -0
  204. package/dist/components/date-picker/date-picker.js +123 -0
  205. package/dist/components/date-picker/date-picker.js.map +1 -0
  206. package/dist/components/date-picker/index.d.ts +2 -0
  207. package/dist/components/date-picker/index.js +2 -0
  208. package/dist/components/date-picker/meta.js +21 -0
  209. package/dist/components/date-picker/meta.js.map +1 -0
  210. package/dist/components/dialog/dialog.d.ts +30 -0
  211. package/dist/components/dialog/dialog.d.ts.map +1 -0
  212. package/dist/components/dialog/dialog.js +79 -0
  213. package/dist/components/dialog/dialog.js.map +1 -0
  214. package/dist/components/dialog/index.d.ts +2 -0
  215. package/dist/components/dialog/index.js +2 -0
  216. package/dist/components/dialog/meta.js +17 -0
  217. package/dist/components/dialog/meta.js.map +1 -0
  218. package/dist/components/drawer/drawer.d.ts +32 -0
  219. package/dist/components/drawer/drawer.d.ts.map +1 -0
  220. package/dist/components/drawer/drawer.js +153 -0
  221. package/dist/components/drawer/drawer.js.map +1 -0
  222. package/dist/components/drawer/index.d.ts +2 -0
  223. package/dist/components/drawer/index.js +2 -0
  224. package/dist/components/drawer/meta.js +17 -0
  225. package/dist/components/drawer/meta.js.map +1 -0
  226. package/dist/components/dropdown-menu/dropdown-menu.d.ts +43 -0
  227. package/dist/components/dropdown-menu/dropdown-menu.d.ts.map +1 -0
  228. package/dist/components/dropdown-menu/dropdown-menu.js +130 -0
  229. package/dist/components/dropdown-menu/dropdown-menu.js.map +1 -0
  230. package/dist/components/dropdown-menu/index.d.ts +2 -0
  231. package/dist/components/dropdown-menu/index.js +2 -0
  232. package/dist/components/dropdown-menu/meta.js +17 -0
  233. package/dist/components/dropdown-menu/meta.js.map +1 -0
  234. package/dist/components/empty-state/empty-state.d.ts +24 -0
  235. package/dist/components/empty-state/empty-state.d.ts.map +1 -0
  236. package/dist/components/empty-state/empty-state.js +73 -0
  237. package/dist/components/empty-state/empty-state.js.map +1 -0
  238. package/dist/components/empty-state/index.d.ts +2 -0
  239. package/dist/components/empty-state/index.js +2 -0
  240. package/dist/components/empty-state/meta.js +17 -0
  241. package/dist/components/empty-state/meta.js.map +1 -0
  242. package/dist/components/form/form.d.ts +43 -0
  243. package/dist/components/form/form.d.ts.map +1 -0
  244. package/dist/components/form/form.js +127 -0
  245. package/dist/components/form/form.js.map +1 -0
  246. package/dist/components/form/index.d.ts +2 -0
  247. package/dist/components/form/index.js +2 -0
  248. package/dist/components/form/meta.js +17 -0
  249. package/dist/components/form/meta.js.map +1 -0
  250. package/dist/components/input/index.d.ts +2 -0
  251. package/dist/components/input/index.js +2 -0
  252. package/dist/components/input/input.d.ts +21 -0
  253. package/dist/components/input/input.d.ts.map +1 -0
  254. package/dist/components/input/input.js +34 -0
  255. package/dist/components/input/input.js.map +1 -0
  256. package/dist/components/input/meta.js +17 -0
  257. package/dist/components/input/meta.js.map +1 -0
  258. package/dist/components/label/index.d.ts +2 -0
  259. package/dist/components/label/index.js +2 -0
  260. package/dist/components/label/label.d.ts +14 -0
  261. package/dist/components/label/label.d.ts.map +1 -0
  262. package/dist/components/label/label.js +20 -0
  263. package/dist/components/label/label.js.map +1 -0
  264. package/dist/components/label/meta.js +17 -0
  265. package/dist/components/label/meta.js.map +1 -0
  266. package/dist/components/pagination/index.d.ts +2 -0
  267. package/dist/components/pagination/index.js +2 -0
  268. package/dist/components/pagination/meta.js +17 -0
  269. package/dist/components/pagination/meta.js.map +1 -0
  270. package/dist/components/pagination/pagination.d.ts +33 -0
  271. package/dist/components/pagination/pagination.d.ts.map +1 -0
  272. package/dist/components/pagination/pagination.js +143 -0
  273. package/dist/components/pagination/pagination.js.map +1 -0
  274. package/dist/components/popover/index.d.ts +2 -0
  275. package/dist/components/popover/index.js +2 -0
  276. package/dist/components/popover/meta.js +17 -0
  277. package/dist/components/popover/meta.js.map +1 -0
  278. package/dist/components/popover/popover.d.ts +24 -0
  279. package/dist/components/popover/popover.d.ts.map +1 -0
  280. package/dist/components/popover/popover.js +60 -0
  281. package/dist/components/popover/popover.js.map +1 -0
  282. package/dist/components/progress/index.d.ts +2 -0
  283. package/dist/components/progress/index.js +2 -0
  284. package/dist/components/progress/meta.js +17 -0
  285. package/dist/components/progress/meta.js.map +1 -0
  286. package/dist/components/progress/progress.d.ts +21 -0
  287. package/dist/components/progress/progress.d.ts.map +1 -0
  288. package/dist/components/progress/progress.js +55 -0
  289. package/dist/components/progress/progress.js.map +1 -0
  290. package/dist/components/radio-group/index.d.ts +2 -0
  291. package/dist/components/radio-group/index.js +2 -0
  292. package/dist/components/radio-group/meta.js +17 -0
  293. package/dist/components/radio-group/meta.js.map +1 -0
  294. package/dist/components/radio-group/radio-group.d.ts +17 -0
  295. package/dist/components/radio-group/radio-group.d.ts.map +1 -0
  296. package/dist/components/radio-group/radio-group.js +29 -0
  297. package/dist/components/radio-group/radio-group.js.map +1 -0
  298. package/dist/components/select/index.d.ts +2 -0
  299. package/dist/components/select/index.js +2 -0
  300. package/dist/components/select/meta.js +17 -0
  301. package/dist/components/select/meta.js.map +1 -0
  302. package/dist/components/select/select.d.ts +37 -0
  303. package/dist/components/select/select.d.ts.map +1 -0
  304. package/dist/components/select/select.js +128 -0
  305. package/dist/components/select/select.js.map +1 -0
  306. package/dist/components/separator/index.d.ts +2 -0
  307. package/dist/components/separator/index.js +2 -0
  308. package/dist/components/separator/meta.js +17 -0
  309. package/dist/components/separator/meta.js.map +1 -0
  310. package/dist/components/separator/separator.d.ts +15 -0
  311. package/dist/components/separator/separator.d.ts.map +1 -0
  312. package/dist/components/separator/separator.js +23 -0
  313. package/dist/components/separator/separator.js.map +1 -0
  314. package/dist/components/sheet/index.d.ts +2 -0
  315. package/dist/components/sheet/index.js +2 -0
  316. package/dist/components/sheet/meta.js +17 -0
  317. package/dist/components/sheet/meta.js.map +1 -0
  318. package/dist/components/sheet/sheet.d.ts +31 -0
  319. package/dist/components/sheet/sheet.d.ts.map +1 -0
  320. package/dist/components/sheet/sheet.js +90 -0
  321. package/dist/components/sheet/sheet.js.map +1 -0
  322. package/dist/components/skeleton/index.d.ts +2 -0
  323. package/dist/components/skeleton/index.js +2 -0
  324. package/dist/components/skeleton/meta.js +17 -0
  325. package/dist/components/skeleton/meta.js.map +1 -0
  326. package/dist/components/skeleton/skeleton.d.ts +20 -0
  327. package/dist/components/skeleton/skeleton.d.ts.map +1 -0
  328. package/dist/components/skeleton/skeleton.js +29 -0
  329. package/dist/components/skeleton/skeleton.js.map +1 -0
  330. package/dist/components/slider/index.d.ts +2 -0
  331. package/dist/components/slider/index.js +2 -0
  332. package/dist/components/slider/meta.js +17 -0
  333. package/dist/components/slider/meta.js.map +1 -0
  334. package/dist/components/slider/slider.d.ts +29 -0
  335. package/dist/components/slider/slider.d.ts.map +1 -0
  336. package/dist/components/slider/slider.js +61 -0
  337. package/dist/components/slider/slider.js.map +1 -0
  338. package/dist/components/spinner/index.d.ts +2 -0
  339. package/dist/components/spinner/index.js +2 -0
  340. package/dist/components/spinner/meta.js +17 -0
  341. package/dist/components/spinner/meta.js.map +1 -0
  342. package/dist/components/spinner/spinner.d.ts +21 -0
  343. package/dist/components/spinner/spinner.d.ts.map +1 -0
  344. package/dist/components/spinner/spinner.js +45 -0
  345. package/dist/components/spinner/spinner.js.map +1 -0
  346. package/dist/components/switch/index.d.ts +2 -0
  347. package/dist/components/switch/index.js +2 -0
  348. package/dist/components/switch/meta.js +17 -0
  349. package/dist/components/switch/meta.js.map +1 -0
  350. package/dist/components/switch/switch.d.ts +15 -0
  351. package/dist/components/switch/switch.d.ts.map +1 -0
  352. package/dist/components/switch/switch.js +21 -0
  353. package/dist/components/switch/switch.js.map +1 -0
  354. package/dist/components/table/index.d.ts +2 -0
  355. package/dist/components/table/index.js +2 -0
  356. package/dist/components/table/meta.js +17 -0
  357. package/dist/components/table/meta.js.map +1 -0
  358. package/dist/components/table/table.d.ts +41 -0
  359. package/dist/components/table/table.d.ts.map +1 -0
  360. package/dist/components/table/table.js +78 -0
  361. package/dist/components/table/table.js.map +1 -0
  362. package/dist/components/tabs/index.d.ts +2 -0
  363. package/dist/components/tabs/index.js +2 -0
  364. package/dist/components/tabs/meta.js +17 -0
  365. package/dist/components/tabs/meta.js.map +1 -0
  366. package/dist/components/tabs/tabs.d.ts +28 -0
  367. package/dist/components/tabs/tabs.d.ts.map +1 -0
  368. package/dist/components/tabs/tabs.js +58 -0
  369. package/dist/components/tabs/tabs.js.map +1 -0
  370. package/dist/components/toast/index.d.ts +3 -0
  371. package/dist/components/toast/index.js +3 -0
  372. package/dist/components/toast/meta.js +17 -0
  373. package/dist/components/toast/meta.js.map +1 -0
  374. package/dist/components/toast/toast-store.d.ts +84 -0
  375. package/dist/components/toast/toast-store.d.ts.map +1 -0
  376. package/dist/components/toast/toast-store.js +115 -0
  377. package/dist/components/toast/toast-store.js.map +1 -0
  378. package/dist/components/toast/toast.d.ts +39 -0
  379. package/dist/components/toast/toast.d.ts.map +1 -0
  380. package/dist/components/toast/toast.js +140 -0
  381. package/dist/components/toast/toast.js.map +1 -0
  382. package/dist/components/tooltip/index.d.ts +2 -0
  383. package/dist/components/tooltip/index.js +2 -0
  384. package/dist/components/tooltip/meta.js +17 -0
  385. package/dist/components/tooltip/meta.js.map +1 -0
  386. package/dist/components/tooltip/tooltip.d.ts +24 -0
  387. package/dist/components/tooltip/tooltip.d.ts.map +1 -0
  388. package/dist/components/tooltip/tooltip.js +38 -0
  389. package/dist/components/tooltip/tooltip.js.map +1 -0
  390. package/dist/index.d.ts +97 -0
  391. package/dist/index.js +51 -0
  392. package/dist/lib/styles.d.ts +21 -0
  393. package/dist/lib/styles.d.ts.map +1 -0
  394. package/dist/lib/styles.js +22 -0
  395. package/dist/lib/styles.js.map +1 -0
  396. package/dist/lib/utils.d.ts +11 -0
  397. package/dist/lib/utils.d.ts.map +1 -0
  398. package/dist/lib/utils.js +21 -0
  399. package/dist/lib/utils.js.map +1 -0
  400. package/dist/registry/blocks.d.ts +15 -0
  401. package/dist/registry/blocks.d.ts.map +1 -0
  402. package/dist/registry/blocks.js +32 -0
  403. package/dist/registry/blocks.js.map +1 -0
  404. package/dist/registry/components.d.ts +18 -0
  405. package/dist/registry/components.d.ts.map +1 -0
  406. package/dist/registry/components.js +112 -0
  407. package/dist/registry/components.js.map +1 -0
  408. package/dist/registry/schema.d.ts +44 -0
  409. package/dist/registry/schema.d.ts.map +1 -0
  410. package/dist/registry/schema.js +33 -0
  411. package/dist/registry/schema.js.map +1 -0
  412. package/package.json +74 -0
  413. package/src/blocks/admin-users/admin-users.stories.tsx +83 -0
  414. package/src/blocks/admin-users/admin-users.test.tsx +159 -0
  415. package/src/blocks/admin-users/admin-users.tsx +251 -0
  416. package/src/blocks/admin-users/index.ts +1 -0
  417. package/src/blocks/admin-users/meta.ts +27 -0
  418. package/src/blocks/ai-chat/ai-chat.stories.tsx +149 -0
  419. package/src/blocks/ai-chat/ai-chat.test.tsx +166 -0
  420. package/src/blocks/ai-chat/ai-chat.tsx +280 -0
  421. package/src/blocks/ai-chat/index.ts +7 -0
  422. package/src/blocks/ai-chat/meta.ts +32 -0
  423. package/src/blocks/dashboard/dashboard.stories.tsx +106 -0
  424. package/src/blocks/dashboard/dashboard.test.tsx +94 -0
  425. package/src/blocks/dashboard/dashboard.tsx +192 -0
  426. package/src/blocks/dashboard/index.ts +6 -0
  427. package/src/blocks/dashboard/meta.ts +18 -0
  428. package/src/blocks/forgot-password/forgot-password.stories.tsx +41 -0
  429. package/src/blocks/forgot-password/forgot-password.test.tsx +62 -0
  430. package/src/blocks/forgot-password/forgot-password.tsx +158 -0
  431. package/src/blocks/forgot-password/index.ts +1 -0
  432. package/src/blocks/forgot-password/meta.ts +18 -0
  433. package/src/blocks/login/index.ts +1 -0
  434. package/src/blocks/login/login.stories.tsx +46 -0
  435. package/src/blocks/login/login.test.tsx +100 -0
  436. package/src/blocks/login/login.tsx +178 -0
  437. package/src/blocks/login/meta.ts +18 -0
  438. package/src/blocks/pricing/index.ts +1 -0
  439. package/src/blocks/pricing/meta.ts +18 -0
  440. package/src/blocks/pricing/pricing.stories.tsx +62 -0
  441. package/src/blocks/pricing/pricing.test.tsx +101 -0
  442. package/src/blocks/pricing/pricing.tsx +176 -0
  443. package/src/blocks/settings/index.ts +6 -0
  444. package/src/blocks/settings/meta.ts +29 -0
  445. package/src/blocks/settings/settings.stories.tsx +94 -0
  446. package/src/blocks/settings/settings.test.tsx +167 -0
  447. package/src/blocks/settings/settings.tsx +317 -0
  448. package/src/blocks/signup/index.ts +1 -0
  449. package/src/blocks/signup/meta.ts +18 -0
  450. package/src/blocks/signup/signup.stories.tsx +27 -0
  451. package/src/blocks/signup/signup.test.tsx +97 -0
  452. package/src/blocks/signup/signup.tsx +240 -0
  453. package/src/components/accordion/accordion.stories.tsx +90 -0
  454. package/src/components/accordion/accordion.test.tsx +156 -0
  455. package/src/components/accordion/accordion.tsx +88 -0
  456. package/src/components/accordion/index.ts +9 -0
  457. package/src/components/accordion/meta.ts +16 -0
  458. package/src/components/activity-feed/activity-feed.stories.tsx +163 -0
  459. package/src/components/activity-feed/activity-feed.test.tsx +125 -0
  460. package/src/components/activity-feed/activity-feed.tsx +115 -0
  461. package/src/components/activity-feed/index.ts +12 -0
  462. package/src/components/activity-feed/meta.ts +17 -0
  463. package/src/components/ai-agent-status/ai-agent-status.stories.tsx +86 -0
  464. package/src/components/ai-agent-status/ai-agent-status.test.tsx +66 -0
  465. package/src/components/ai-agent-status/ai-agent-status.tsx +88 -0
  466. package/src/components/ai-agent-status/index.ts +6 -0
  467. package/src/components/ai-agent-status/meta.ts +17 -0
  468. package/src/components/ai-conversation/ai-conversation.stories.tsx +126 -0
  469. package/src/components/ai-conversation/ai-conversation.test.tsx +144 -0
  470. package/src/components/ai-conversation/ai-conversation.tsx +229 -0
  471. package/src/components/ai-conversation/index.ts +9 -0
  472. package/src/components/ai-conversation/meta.ts +20 -0
  473. package/src/components/ai-message/ai-message.stories.tsx +106 -0
  474. package/src/components/ai-message/ai-message.test.tsx +160 -0
  475. package/src/components/ai-message/ai-message.tsx +162 -0
  476. package/src/components/ai-message/index.ts +13 -0
  477. package/src/components/ai-message/meta.ts +17 -0
  478. package/src/components/ai-model-selector/ai-model-selector.stories.tsx +66 -0
  479. package/src/components/ai-model-selector/ai-model-selector.test.tsx +120 -0
  480. package/src/components/ai-model-selector/ai-model-selector.tsx +112 -0
  481. package/src/components/ai-model-selector/index.ts +1 -0
  482. package/src/components/ai-model-selector/meta.ts +17 -0
  483. package/src/components/ai-prompt-input/ai-prompt-input.stories.tsx +145 -0
  484. package/src/components/ai-prompt-input/ai-prompt-input.test.tsx +273 -0
  485. package/src/components/ai-prompt-input/ai-prompt-input.tsx +306 -0
  486. package/src/components/ai-prompt-input/index.ts +11 -0
  487. package/src/components/ai-prompt-input/meta.ts +18 -0
  488. package/src/components/ai-reasoning/ai-reasoning.stories.tsx +60 -0
  489. package/src/components/ai-reasoning/ai-reasoning.test.tsx +95 -0
  490. package/src/components/ai-reasoning/ai-reasoning.tsx +106 -0
  491. package/src/components/ai-reasoning/index.ts +7 -0
  492. package/src/components/ai-reasoning/meta.ts +17 -0
  493. package/src/components/ai-response/ai-response.stories.tsx +75 -0
  494. package/src/components/ai-response/ai-response.test.tsx +96 -0
  495. package/src/components/ai-response/ai-response.tsx +95 -0
  496. package/src/components/ai-response/index.ts +7 -0
  497. package/src/components/ai-response/meta.ts +17 -0
  498. package/src/components/ai-sources/ai-sources.stories.tsx +93 -0
  499. package/src/components/ai-sources/ai-sources.test.tsx +102 -0
  500. package/src/components/ai-sources/ai-sources.tsx +186 -0
  501. package/src/components/ai-sources/index.ts +11 -0
  502. package/src/components/ai-sources/meta.ts +17 -0
  503. package/src/components/ai-token-usage/ai-token-usage.stories.tsx +59 -0
  504. package/src/components/ai-token-usage/ai-token-usage.test.tsx +83 -0
  505. package/src/components/ai-token-usage/ai-token-usage.tsx +105 -0
  506. package/src/components/ai-token-usage/index.ts +6 -0
  507. package/src/components/ai-token-usage/meta.ts +16 -0
  508. package/src/components/ai-tool/ai-tool.stories.tsx +96 -0
  509. package/src/components/ai-tool/ai-tool.test.tsx +137 -0
  510. package/src/components/ai-tool/ai-tool.tsx +235 -0
  511. package/src/components/ai-tool/index.ts +13 -0
  512. package/src/components/ai-tool/meta.ts +17 -0
  513. package/src/components/alert/alert.stories.tsx +101 -0
  514. package/src/components/alert/alert.test.tsx +94 -0
  515. package/src/components/alert/alert.tsx +89 -0
  516. package/src/components/alert/index.ts +8 -0
  517. package/src/components/alert/meta.ts +16 -0
  518. package/src/components/avatar/avatar.stories.tsx +58 -0
  519. package/src/components/avatar/avatar.test.tsx +64 -0
  520. package/src/components/avatar/avatar.tsx +68 -0
  521. package/src/components/avatar/index.ts +9 -0
  522. package/src/components/avatar/meta.ts +15 -0
  523. package/src/components/badge/badge.stories.tsx +68 -0
  524. package/src/components/badge/badge.test.tsx +61 -0
  525. package/src/components/badge/badge.tsx +54 -0
  526. package/src/components/badge/index.ts +1 -0
  527. package/src/components/badge/meta.ts +15 -0
  528. package/src/components/button/button.stories.tsx +128 -0
  529. package/src/components/button/button.test.tsx +224 -0
  530. package/src/components/button/button.tsx +114 -0
  531. package/src/components/button/index.ts +1 -0
  532. package/src/components/button/meta.ts +16 -0
  533. package/src/components/calendar/calendar.stories.tsx +105 -0
  534. package/src/components/calendar/calendar.test.tsx +255 -0
  535. package/src/components/calendar/calendar.tsx +115 -0
  536. package/src/components/calendar/index.ts +1 -0
  537. package/src/components/calendar/meta.ts +17 -0
  538. package/src/components/card/card.stories.tsx +61 -0
  539. package/src/components/card/card.test.tsx +66 -0
  540. package/src/components/card/card.tsx +81 -0
  541. package/src/components/card/index.ts +9 -0
  542. package/src/components/card/meta.ts +16 -0
  543. package/src/components/checkbox/checkbox.stories.tsx +124 -0
  544. package/src/components/checkbox/checkbox.test.tsx +121 -0
  545. package/src/components/checkbox/checkbox.tsx +66 -0
  546. package/src/components/checkbox/index.ts +1 -0
  547. package/src/components/checkbox/meta.ts +16 -0
  548. package/src/components/code-block/code-block.stories.tsx +62 -0
  549. package/src/components/code-block/code-block.test.tsx +139 -0
  550. package/src/components/code-block/code-block.tsx +188 -0
  551. package/src/components/code-block/index.ts +1 -0
  552. package/src/components/code-block/meta.ts +17 -0
  553. package/src/components/combobox/combobox.stories.tsx +171 -0
  554. package/src/components/combobox/combobox.test.tsx +429 -0
  555. package/src/components/combobox/combobox.tsx +544 -0
  556. package/src/components/combobox/index.ts +15 -0
  557. package/src/components/combobox/meta.ts +17 -0
  558. package/src/components/command/command.stories.tsx +152 -0
  559. package/src/components/command/command.test.tsx +380 -0
  560. package/src/components/command/command.tsx +482 -0
  561. package/src/components/command/index.ts +17 -0
  562. package/src/components/command/meta.ts +18 -0
  563. package/src/components/data-table/data-table.stories.tsx +151 -0
  564. package/src/components/data-table/data-table.test.tsx +288 -0
  565. package/src/components/data-table/data-table.tsx +485 -0
  566. package/src/components/data-table/index.ts +13 -0
  567. package/src/components/data-table/meta.ts +19 -0
  568. package/src/components/date-picker/date-picker.stories.tsx +103 -0
  569. package/src/components/date-picker/date-picker.test.tsx +205 -0
  570. package/src/components/date-picker/date-picker.tsx +198 -0
  571. package/src/components/date-picker/index.ts +6 -0
  572. package/src/components/date-picker/meta.ts +18 -0
  573. package/src/components/dialog/dialog.stories.tsx +140 -0
  574. package/src/components/dialog/dialog.test.tsx +186 -0
  575. package/src/components/dialog/dialog.tsx +132 -0
  576. package/src/components/dialog/index.ts +16 -0
  577. package/src/components/dialog/meta.ts +16 -0
  578. package/src/components/drawer/drawer.stories.tsx +111 -0
  579. package/src/components/drawer/drawer.test.tsx +187 -0
  580. package/src/components/drawer/drawer.tsx +293 -0
  581. package/src/components/drawer/index.ts +16 -0
  582. package/src/components/drawer/meta.ts +16 -0
  583. package/src/components/dropdown-menu/dropdown-menu.stories.tsx +128 -0
  584. package/src/components/dropdown-menu/dropdown-menu.test.tsx +321 -0
  585. package/src/components/dropdown-menu/dropdown-menu.tsx +242 -0
  586. package/src/components/dropdown-menu/index.ts +21 -0
  587. package/src/components/dropdown-menu/meta.ts +17 -0
  588. package/src/components/empty-state/empty-state.stories.tsx +70 -0
  589. package/src/components/empty-state/empty-state.test.tsx +97 -0
  590. package/src/components/empty-state/empty-state.tsx +92 -0
  591. package/src/components/empty-state/index.ts +9 -0
  592. package/src/components/empty-state/meta.ts +16 -0
  593. package/src/components/form/form.stories.tsx +144 -0
  594. package/src/components/form/form.test.tsx +203 -0
  595. package/src/components/form/form.tsx +221 -0
  596. package/src/components/form/index.ts +13 -0
  597. package/src/components/form/meta.ts +17 -0
  598. package/src/components/input/index.ts +1 -0
  599. package/src/components/input/input.stories.tsx +84 -0
  600. package/src/components/input/input.test.tsx +108 -0
  601. package/src/components/input/input.tsx +51 -0
  602. package/src/components/input/meta.ts +15 -0
  603. package/src/components/label/index.ts +1 -0
  604. package/src/components/label/label.stories.tsx +51 -0
  605. package/src/components/label/label.test.tsx +55 -0
  606. package/src/components/label/label.tsx +26 -0
  607. package/src/components/label/meta.ts +15 -0
  608. package/src/components/pagination/index.ts +10 -0
  609. package/src/components/pagination/meta.ts +17 -0
  610. package/src/components/pagination/pagination.stories.tsx +129 -0
  611. package/src/components/pagination/pagination.test.tsx +119 -0
  612. package/src/components/pagination/pagination.tsx +142 -0
  613. package/src/components/popover/index.ts +9 -0
  614. package/src/components/popover/meta.ts +18 -0
  615. package/src/components/popover/popover.stories.tsx +84 -0
  616. package/src/components/popover/popover.test.tsx +163 -0
  617. package/src/components/popover/popover.tsx +89 -0
  618. package/src/components/progress/index.ts +1 -0
  619. package/src/components/progress/meta.ts +17 -0
  620. package/src/components/progress/progress.stories.tsx +90 -0
  621. package/src/components/progress/progress.test.tsx +78 -0
  622. package/src/components/progress/progress.tsx +70 -0
  623. package/src/components/radio-group/index.ts +6 -0
  624. package/src/components/radio-group/meta.ts +16 -0
  625. package/src/components/radio-group/radio-group.stories.tsx +102 -0
  626. package/src/components/radio-group/radio-group.test.tsx +152 -0
  627. package/src/components/radio-group/radio-group.tsx +53 -0
  628. package/src/components/select/index.ts +14 -0
  629. package/src/components/select/meta.ts +16 -0
  630. package/src/components/select/select.stories.tsx +137 -0
  631. package/src/components/select/select.test.tsx +209 -0
  632. package/src/components/select/select.tsx +222 -0
  633. package/src/components/separator/index.ts +1 -0
  634. package/src/components/separator/meta.ts +15 -0
  635. package/src/components/separator/separator.stories.tsx +42 -0
  636. package/src/components/separator/separator.test.tsx +46 -0
  637. package/src/components/separator/separator.tsx +33 -0
  638. package/src/components/sheet/index.ts +14 -0
  639. package/src/components/sheet/meta.ts +16 -0
  640. package/src/components/sheet/sheet.stories.tsx +107 -0
  641. package/src/components/sheet/sheet.test.tsx +152 -0
  642. package/src/components/sheet/sheet.tsx +160 -0
  643. package/src/components/skeleton/index.ts +1 -0
  644. package/src/components/skeleton/meta.ts +15 -0
  645. package/src/components/skeleton/skeleton.stories.tsx +46 -0
  646. package/src/components/skeleton/skeleton.test.tsx +57 -0
  647. package/src/components/skeleton/skeleton.tsx +28 -0
  648. package/src/components/slider/index.ts +1 -0
  649. package/src/components/slider/meta.ts +19 -0
  650. package/src/components/slider/slider.stories.tsx +87 -0
  651. package/src/components/slider/slider.test.tsx +148 -0
  652. package/src/components/slider/slider.tsx +135 -0
  653. package/src/components/spinner/index.ts +1 -0
  654. package/src/components/spinner/meta.ts +15 -0
  655. package/src/components/spinner/spinner.stories.tsx +47 -0
  656. package/src/components/spinner/spinner.test.tsx +41 -0
  657. package/src/components/spinner/spinner.tsx +68 -0
  658. package/src/components/switch/index.ts +1 -0
  659. package/src/components/switch/meta.ts +15 -0
  660. package/src/components/switch/switch.stories.tsx +70 -0
  661. package/src/components/switch/switch.test.tsx +101 -0
  662. package/src/components/switch/switch.tsx +42 -0
  663. package/src/components/table/index.ts +11 -0
  664. package/src/components/table/meta.ts +17 -0
  665. package/src/components/table/table.stories.tsx +131 -0
  666. package/src/components/table/table.test.tsx +153 -0
  667. package/src/components/table/table.tsx +138 -0
  668. package/src/components/tabs/index.ts +11 -0
  669. package/src/components/tabs/meta.ts +17 -0
  670. package/src/components/tabs/tabs.stories.tsx +139 -0
  671. package/src/components/tabs/tabs.test.tsx +148 -0
  672. package/src/components/tabs/tabs.tsx +106 -0
  673. package/src/components/toast/index.ts +24 -0
  674. package/src/components/toast/meta.ts +18 -0
  675. package/src/components/toast/toast-store.ts +181 -0
  676. package/src/components/toast/toast.stories.tsx +167 -0
  677. package/src/components/toast/toast.test.tsx +306 -0
  678. package/src/components/toast/toast.tsx +241 -0
  679. package/src/components/tooltip/index.ts +8 -0
  680. package/src/components/tooltip/meta.ts +17 -0
  681. package/src/components/tooltip/tooltip.stories.tsx +89 -0
  682. package/src/components/tooltip/tooltip.test.tsx +120 -0
  683. package/src/components/tooltip/tooltip.tsx +58 -0
  684. package/src/index.ts +50 -0
  685. package/src/lib/styles.ts +26 -0
  686. package/src/lib/utils.test.ts +32 -0
  687. package/src/lib/utils.ts +24 -0
  688. package/src/registry/blocks.ts +30 -0
  689. package/src/registry/components.ts +114 -0
  690. package/src/registry/meta.test.ts +234 -0
  691. package/src/registry/schema.ts +58 -0
@@ -0,0 +1,18 @@
1
+ import { defineMeta } from "@/registry/schema";
2
+
3
+ export const meta = defineMeta({
4
+ name: "forgot-password",
5
+ kind: "block",
6
+ title: "Forgot password",
7
+ description:
8
+ "A password reset request, with a confirmation that does not leak account existence.",
9
+ category: "form",
10
+ status: "stable",
11
+ dependencies: [],
12
+ registryDependencies: ["button", "card", "empty-state", "form", "input"],
13
+ files: ["forgot-password.tsx"],
14
+ a11y:
15
+ "The confirmation replaces the form, so it is a polite live region — otherwise a screen " +
16
+ "reader user submits and hears nothing. The wording is deliberately neutral about whether " +
17
+ "the address exists: confirming it would turn this form into an account enumeration oracle.",
18
+ });
@@ -0,0 +1 @@
1
+ export { LoginBlock, type LoginBlockProps } from "./login";
@@ -0,0 +1,46 @@
1
+ import type { Meta, StoryObj } from "@storybook/react-vite";
2
+ import { useState } from "react";
3
+
4
+ import { LoginBlock } from "./login";
5
+
6
+ const meta = {
7
+ title: "Blocks/Login",
8
+ component: LoginBlock,
9
+ parameters: { layout: "centered", controls: { disable: true } },
10
+ } satisfies Meta<typeof LoginBlock>;
11
+
12
+ export default meta;
13
+ type Story = StoryObj<typeof meta>;
14
+
15
+ export const Default: Story = {};
16
+
17
+ export const WithServerError: Story = {
18
+ args: { error: "Those credentials did not match our records." },
19
+ };
20
+
21
+ export const Submitting: Story = {
22
+ args: { pending: true },
23
+ };
24
+
25
+ /** The whole round trip: submit, wait, fail. */
26
+ export const Interactive: Story = {
27
+ render: function Interactive() {
28
+ const [pending, setPending] = useState(false);
29
+ const [error, setError] = useState<string | undefined>(undefined);
30
+
31
+ return (
32
+ <LoginBlock
33
+ pending={pending}
34
+ error={error}
35
+ onSubmit={() => {
36
+ setError(undefined);
37
+ setPending(true);
38
+ window.setTimeout(() => {
39
+ setPending(false);
40
+ setError("Those credentials did not match our records.");
41
+ }, 1200);
42
+ }}
43
+ />
44
+ );
45
+ },
46
+ };
@@ -0,0 +1,100 @@
1
+ import { render, screen } from "@testing-library/react";
2
+ import userEvent from "@testing-library/user-event";
3
+ import { describe, expect, it, vi } from "vitest";
4
+
5
+ import { expectNoA11yViolations } from "../../../test/a11y";
6
+ import { LoginBlock } from "./login";
7
+
8
+ describe("LoginBlock", () => {
9
+ it("labels every field", () => {
10
+ render(<LoginBlock />);
11
+ expect(screen.getByLabelText("Email")).toBeInTheDocument();
12
+ expect(screen.getByLabelText("Password")).toBeInTheDocument();
13
+ expect(screen.getByLabelText("Keep me signed in")).toBeInTheDocument();
14
+ });
15
+
16
+ it("uses the right input types and autocomplete", () => {
17
+ render(<LoginBlock />);
18
+
19
+ const email = screen.getByLabelText("Email");
20
+ expect(email).toHaveAttribute("type", "email");
21
+ expect(email).toHaveAttribute("autocomplete", "email");
22
+ expect(screen.getByLabelText("Password")).toHaveAttribute(
23
+ "autocomplete",
24
+ "current-password",
25
+ );
26
+ });
27
+
28
+ it("submits valid credentials", async () => {
29
+ const onSubmit = vi.fn();
30
+ const user = userEvent.setup();
31
+ render(<LoginBlock onSubmit={onSubmit} />);
32
+
33
+ await user.type(screen.getByLabelText("Email"), "ada@example.com");
34
+ await user.type(screen.getByLabelText("Password"), "correct horse");
35
+ await user.click(screen.getByRole("button", { name: "Sign in" }));
36
+
37
+ expect(onSubmit).toHaveBeenCalledWith({
38
+ email: "ada@example.com",
39
+ password: "correct horse",
40
+ remember: false,
41
+ });
42
+ });
43
+
44
+ it("reports the remember choice", async () => {
45
+ const onSubmit = vi.fn();
46
+ const user = userEvent.setup();
47
+ render(<LoginBlock onSubmit={onSubmit} />);
48
+
49
+ await user.type(screen.getByLabelText("Email"), "ada@example.com");
50
+ await user.type(screen.getByLabelText("Password"), "secret");
51
+ await user.click(screen.getByLabelText("Keep me signed in"));
52
+ await user.click(screen.getByRole("button", { name: "Sign in" }));
53
+
54
+ expect(onSubmit).toHaveBeenCalledWith(expect.objectContaining({ remember: true }));
55
+ });
56
+
57
+ it("does not submit an invalid form, and ties the error to the field", async () => {
58
+ const onSubmit = vi.fn();
59
+ const user = userEvent.setup();
60
+ render(<LoginBlock onSubmit={onSubmit} />);
61
+
62
+ await user.type(screen.getByLabelText("Email"), "nope");
63
+ await user.click(screen.getByRole("button", { name: "Sign in" }));
64
+
65
+ expect(onSubmit).not.toHaveBeenCalled();
66
+ const email = screen.getByLabelText("Email");
67
+ expect(email).toHaveAttribute("aria-invalid", "true");
68
+ expect(email).toHaveAccessibleDescription("Enter a valid email address.");
69
+ });
70
+
71
+ it("announces a server error assertively", () => {
72
+ render(<LoginBlock error="Those credentials did not match." />);
73
+ // It arrived after the user acted and explains why nothing happened.
74
+ expect(screen.getByRole("alert")).toHaveTextContent("Those credentials did not match.");
75
+ });
76
+
77
+ it("reports its busy state on the submit button", () => {
78
+ render(<LoginBlock pending />);
79
+ const submit = screen.getByRole("button", { name: "Sign in" });
80
+ expect(submit).toHaveAttribute("aria-busy", "true");
81
+ expect(screen.getByLabelText("Email")).toBeDisabled();
82
+ });
83
+
84
+ it("links to password recovery and sign-up", () => {
85
+ render(<LoginBlock forgotHref="/reset" signupHref="/register" />);
86
+ expect(screen.getByRole("link", { name: "Forgot password?" })).toHaveAttribute(
87
+ "href",
88
+ "/reset",
89
+ );
90
+ expect(screen.getByRole("link", { name: "Create one" })).toHaveAttribute(
91
+ "href",
92
+ "/register",
93
+ );
94
+ });
95
+
96
+ it("has no accessibility violations", async () => {
97
+ const { container } = render(<LoginBlock error="Those credentials did not match." />);
98
+ await expectNoA11yViolations(container);
99
+ });
100
+ });
@@ -0,0 +1,178 @@
1
+ "use client";
2
+
3
+ import { useState, type FormEvent } from "react";
4
+
5
+ import { Button } from "@/components/button";
6
+ import {
7
+ Card,
8
+ CardContent,
9
+ CardDescription,
10
+ CardFooter,
11
+ CardHeader,
12
+ CardTitle,
13
+ } from "@/components/card";
14
+ import { Checkbox } from "@/components/checkbox";
15
+ import { Form, FormControl, FormField, FormLabel, FormMessage } from "@/components/form";
16
+ import { Input } from "@/components/input";
17
+ import { Label } from "@/components/label";
18
+ import { Separator } from "@/components/separator";
19
+ import { cn } from "@/lib/utils";
20
+
21
+ /**
22
+ * A sign-in form.
23
+ *
24
+ * Wired for the parts that are easy to get wrong rather than left as markup:
25
+ * the email field is typed and autocompleted correctly, errors are announced,
26
+ * and the submit button reports its own busy state instead of leaving people
27
+ * wondering whether the click registered.
28
+ *
29
+ * Validation here is the minimum that makes the form usable offline. Real
30
+ * validation belongs to whatever the form is submitted to — pass `error` for a
31
+ * server response.
32
+ */
33
+
34
+ export interface LoginBlockProps {
35
+ /** Called with the submitted credentials. */
36
+ onSubmit?: (values: { email: string; password: string; remember: boolean }) => void;
37
+ /** A server-side error, shown above the fields. */
38
+ error?: string;
39
+ /** Disables the form and shows the submit button as busy. */
40
+ pending?: boolean;
41
+ /** Where "Forgot password?" goes. */
42
+ forgotHref?: string;
43
+ /** Where "Create an account" goes. */
44
+ signupHref?: string;
45
+ className?: string;
46
+ }
47
+
48
+ export function LoginBlock({
49
+ onSubmit,
50
+ error,
51
+ pending = false,
52
+ forgotHref = "/forgot-password",
53
+ signupHref = "/signup",
54
+ className,
55
+ }: LoginBlockProps) {
56
+ const [email, setEmail] = useState("");
57
+ const [password, setPassword] = useState("");
58
+ const [remember, setRemember] = useState(false);
59
+ const [touched, setTouched] = useState(false);
60
+
61
+ const emailError =
62
+ touched && !email.includes("@") ? "Enter a valid email address." : undefined;
63
+ const passwordError = touched && password.length === 0 ? "Enter your password." : undefined;
64
+
65
+ function handleSubmit(event: FormEvent<HTMLFormElement>) {
66
+ event.preventDefault();
67
+ setTouched(true);
68
+ if (!email.includes("@") || password.length === 0) return;
69
+ onSubmit?.({ email, password, remember });
70
+ }
71
+
72
+ return (
73
+ <Card className={cn("w-full max-w-sm", className)}>
74
+ <CardHeader>
75
+ <CardTitle>Sign in</CardTitle>
76
+ <CardDescription>Welcome back. Enter your details to continue.</CardDescription>
77
+ </CardHeader>
78
+
79
+ <CardContent>
80
+ <Form onSubmit={handleSubmit} className="gap-4">
81
+ {/* A server error is assertive: it arrived after the user acted, and
82
+ it is the reason nothing happened. */}
83
+ {error ? (
84
+ <p role="alert" className="text-sm font-medium text-destructive">
85
+ {error}
86
+ </p>
87
+ ) : null}
88
+
89
+ <FormField name="email" error={emailError}>
90
+ <FormLabel>Email</FormLabel>
91
+ <FormControl>
92
+ <Input
93
+ type="email"
94
+ autoComplete="email"
95
+ placeholder="you@example.com"
96
+ value={email}
97
+ disabled={pending}
98
+ onChange={(event) => {
99
+ setEmail(event.target.value);
100
+ }}
101
+ />
102
+ </FormControl>
103
+ <FormMessage />
104
+ </FormField>
105
+
106
+ <FormField name="password" error={passwordError}>
107
+ <div className="flex items-center justify-between">
108
+ <FormLabel>Password</FormLabel>
109
+ <a
110
+ href={forgotHref}
111
+ className="text-xs font-medium text-muted-foreground underline underline-offset-4 hover:text-foreground"
112
+ >
113
+ Forgot password?
114
+ </a>
115
+ </div>
116
+ <FormControl>
117
+ <Input
118
+ type="password"
119
+ autoComplete="current-password"
120
+ value={password}
121
+ disabled={pending}
122
+ onChange={(event) => {
123
+ setPassword(event.target.value);
124
+ }}
125
+ />
126
+ </FormControl>
127
+ <FormMessage />
128
+ </FormField>
129
+
130
+ <div className="flex items-center gap-2">
131
+ <Checkbox
132
+ id="remember-me"
133
+ checked={remember}
134
+ disabled={pending}
135
+ onCheckedChange={(checked) => {
136
+ setRemember(checked === true);
137
+ }}
138
+ />
139
+ <Label htmlFor="remember-me" className="text-sm font-normal">
140
+ Keep me signed in
141
+ </Label>
142
+ </div>
143
+
144
+ <Button type="submit" loading={pending} className="w-full">
145
+ Sign in
146
+ </Button>
147
+ </Form>
148
+
149
+ <div className="my-5 flex items-center gap-3">
150
+ <Separator className="flex-1" />
151
+ <span className="text-2xs text-muted-foreground uppercase">or</span>
152
+ <Separator className="flex-1" />
153
+ </div>
154
+
155
+ <div className="grid gap-2">
156
+ <Button variant="outline" className="w-full" disabled={pending}>
157
+ Continue with GitHub
158
+ </Button>
159
+ <Button variant="outline" className="w-full" disabled={pending}>
160
+ Continue with Google
161
+ </Button>
162
+ </div>
163
+ </CardContent>
164
+
165
+ <CardFooter className="justify-center">
166
+ <p className="text-sm text-muted-foreground">
167
+ Don&rsquo;t have an account?{" "}
168
+ <a
169
+ href={signupHref}
170
+ className="font-medium text-primary underline underline-offset-4"
171
+ >
172
+ Create one
173
+ </a>
174
+ </p>
175
+ </CardFooter>
176
+ </Card>
177
+ );
178
+ }
@@ -0,0 +1,18 @@
1
+ import { defineMeta } from "@/registry/schema";
2
+
3
+ export const meta = defineMeta({
4
+ name: "login",
5
+ kind: "block",
6
+ title: "Login",
7
+ description: "A sign-in form with validation, social providers and a busy state.",
8
+ category: "form",
9
+ status: "stable",
10
+ dependencies: [],
11
+ registryDependencies: ["button", "card", "checkbox", "form", "input", "label", "separator"],
12
+ files: ["login.tsx"],
13
+ a11y:
14
+ "Email and password fields carry the right type and autocomplete, so password managers and " +
15
+ "mobile keyboards behave. Field errors are tied to their inputs through the Form wiring; a " +
16
+ "server error is an assertive alert, because it arrived after the user acted and explains why " +
17
+ "nothing happened. The submit button reports its own busy state rather than going quiet.",
18
+ });
@@ -0,0 +1 @@
1
+ export { PricingBlock, type PricingBlockProps, type PricingPlan } from "./pricing";
@@ -0,0 +1,18 @@
1
+ import { defineMeta } from "@/registry/schema";
2
+
3
+ export const meta = defineMeta({
4
+ name: "pricing",
5
+ kind: "block",
6
+ title: "Pricing",
7
+ description: "A pricing section with plan cards and a monthly/yearly toggle.",
8
+ category: "layout",
9
+ status: "stable",
10
+ dependencies: [],
11
+ registryDependencies: ["badge", "button", "card", "label", "switch"],
12
+ files: ["pricing.tsx"],
13
+ a11y:
14
+ "Switching the billing period rewrites every price on the page, so the change is announced " +
15
+ "politely rather than happening silently. Each plan's call to action names the plan — three " +
16
+ 'buttons all reading "Choose" are indistinguishable out of context. Feature ticks are ' +
17
+ "decorative; the feature text carries the meaning.",
18
+ });
@@ -0,0 +1,62 @@
1
+ import type { Decorator, Meta, StoryObj } from "@storybook/react-vite";
2
+
3
+ import { PricingBlock, type PricingPlan } from "./pricing";
4
+
5
+ /** Named so its type is nameable in declaration output (TS2883). */
6
+ const withPageWidth: Decorator = (Story) => (
7
+ <div className="w-[64rem] max-w-full">
8
+ <Story />
9
+ </div>
10
+ );
11
+
12
+ const PLANS: PricingPlan[] = [
13
+ {
14
+ id: "hobby",
15
+ name: "Hobby",
16
+ description: "For personal projects.",
17
+ monthly: 0,
18
+ features: ["1 project", "Community support", "Deploy from Git"],
19
+ cta: "Start free",
20
+ },
21
+ {
22
+ id: "pro",
23
+ name: "Pro",
24
+ description: "For teams shipping to production.",
25
+ monthly: 20,
26
+ yearlyPerMonth: 16,
27
+ features: ["Unlimited projects", "Priority support", "Preview deployments", "Analytics"],
28
+ featured: true,
29
+ },
30
+ {
31
+ id: "enterprise",
32
+ name: "Enterprise",
33
+ description: "For organisations with compliance needs.",
34
+ monthly: null,
35
+ features: ["SSO and SCIM", "Audit logs", "Dedicated support", "Custom contracts"],
36
+ cta: "Talk to sales",
37
+ },
38
+ ];
39
+
40
+ const meta = {
41
+ title: "Blocks/Pricing",
42
+ component: PricingBlock,
43
+ args: { plans: PLANS },
44
+ parameters: { controls: { disable: true } },
45
+ decorators: [withPageWidth],
46
+ } satisfies Meta<typeof PricingBlock>;
47
+
48
+ export default meta;
49
+ type Story = StoryObj<typeof meta>;
50
+
51
+ /** Flip the period: every price changes, and the change is announced. */
52
+ export const Default: Story = {};
53
+
54
+ export const WithoutPeriodToggle: Story = {
55
+ args: { showPeriodToggle: false },
56
+ };
57
+
58
+ export const WithFootnote: Story = {
59
+ args: {
60
+ footnote: "All prices exclude VAT. Cancel at any time.",
61
+ },
62
+ };
@@ -0,0 +1,101 @@
1
+ import { render, screen } from "@testing-library/react";
2
+ import userEvent from "@testing-library/user-event";
3
+ import { describe, expect, it, vi } from "vitest";
4
+
5
+ import { expectNoA11yViolations } from "../../../test/a11y";
6
+ import { PricingBlock, type PricingPlan } from "./pricing";
7
+
8
+ const PLANS: PricingPlan[] = [
9
+ {
10
+ id: "hobby",
11
+ name: "Hobby",
12
+ description: "Personal projects.",
13
+ monthly: 0,
14
+ features: ["1 project"],
15
+ },
16
+ {
17
+ id: "pro",
18
+ name: "Pro",
19
+ description: "Teams shipping to production.",
20
+ monthly: 20,
21
+ yearlyPerMonth: 16,
22
+ features: ["Unlimited projects", "Priority support"],
23
+ featured: true,
24
+ },
25
+ {
26
+ id: "enterprise",
27
+ name: "Enterprise",
28
+ description: "SSO and audit logs.",
29
+ monthly: null,
30
+ features: ["SSO"],
31
+ },
32
+ ];
33
+
34
+ describe("PricingBlock", () => {
35
+ it("renders each plan with its price", () => {
36
+ render(<PricingBlock plans={PLANS} />);
37
+ expect(screen.getByText("$20")).toBeInTheDocument();
38
+ expect(screen.getByText("$0")).toBeInTheDocument();
39
+ });
40
+
41
+ it("shows a custom price as words, not a number", () => {
42
+ render(<PricingBlock plans={PLANS} />);
43
+ expect(screen.getByText("Custom")).toBeInTheDocument();
44
+ });
45
+
46
+ it("names each call to action after its plan", () => {
47
+ render(<PricingBlock plans={PLANS} />);
48
+ // Three buttons all reading "Choose" are indistinguishable out of context.
49
+ expect(screen.getByRole("button", { name: "Choose Pro" })).toBeInTheDocument();
50
+ expect(screen.getByRole("button", { name: "Choose Hobby" })).toBeInTheDocument();
51
+ });
52
+
53
+ it("marks the recommended plan in text", () => {
54
+ render(<PricingBlock plans={PLANS} />);
55
+ expect(screen.getByText("Recommended")).toBeInTheDocument();
56
+ });
57
+
58
+ it("switches every price when the period changes", async () => {
59
+ const user = userEvent.setup();
60
+ render(<PricingBlock plans={PLANS} />);
61
+
62
+ expect(screen.getByText("$20")).toBeInTheDocument();
63
+ await user.click(screen.getByRole("switch", { name: "Bill yearly" }));
64
+ expect(screen.getByText("$16")).toBeInTheDocument();
65
+ });
66
+
67
+ it("announces the period change, since it rewrites the whole page", async () => {
68
+ const user = userEvent.setup();
69
+ render(<PricingBlock plans={PLANS} />);
70
+
71
+ expect(screen.getByText("Showing monthly pricing.")).toBeInTheDocument();
72
+ await user.click(screen.getByRole("switch", { name: "Bill yearly" }));
73
+ expect(screen.getByText("Showing yearly pricing.")).toBeInTheDocument();
74
+ });
75
+
76
+ it("can hide the period toggle", () => {
77
+ render(<PricingBlock plans={PLANS} showPeriodToggle={false} />);
78
+ expect(screen.queryByRole("switch")).not.toBeInTheDocument();
79
+ });
80
+
81
+ it("reports which plan was chosen", async () => {
82
+ const onSelect = vi.fn();
83
+ const user = userEvent.setup();
84
+ render(
85
+ <PricingBlock plans={PLANS.map((p) => (p.id === "pro" ? { ...p, onSelect } : p))} />,
86
+ );
87
+
88
+ await user.click(screen.getByRole("button", { name: "Choose Pro" }));
89
+ expect(onSelect).toHaveBeenCalledTimes(1);
90
+ });
91
+
92
+ it("is a named section", () => {
93
+ render(<PricingBlock plans={PLANS} title="Plans" />);
94
+ expect(screen.getByRole("region", { name: "Plans" })).toBeInTheDocument();
95
+ });
96
+
97
+ it("has no accessibility violations", async () => {
98
+ const { container } = render(<PricingBlock plans={PLANS} />);
99
+ await expectNoA11yViolations(container);
100
+ });
101
+ });