@brcarddev/frontend-commons 1.0.2

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 (490) hide show
  1. package/README.md +241 -0
  2. package/eslint.config.js +190 -0
  3. package/package.json +161 -0
  4. package/src/components/atoms/AudioPlayer/audio-player.stories.tsx +36 -0
  5. package/src/components/atoms/AudioPlayer/audio-player.test.tsx +20 -0
  6. package/src/components/atoms/AudioPlayer/audio-player.tsx +13 -0
  7. package/src/components/atoms/AudioPlayer/index.ts +1 -0
  8. package/src/components/atoms/Badge/badge.stories.tsx +80 -0
  9. package/src/components/atoms/Badge/badge.test.tsx +59 -0
  10. package/src/components/atoms/Badge/badge.tsx +47 -0
  11. package/src/components/atoms/Badge/index.ts +1 -0
  12. package/src/components/atoms/Box/box.stories.tsx +37 -0
  13. package/src/components/atoms/Box/box.test.tsx +47 -0
  14. package/src/components/atoms/Box/box.tsx +7 -0
  15. package/src/components/atoms/Box/index.ts +1 -0
  16. package/src/components/atoms/Button/button.stories.tsx +108 -0
  17. package/src/components/atoms/Button/button.test.tsx +54 -0
  18. package/src/components/atoms/Button/button.tsx +96 -0
  19. package/src/components/atoms/Button/index.ts +1 -0
  20. package/src/components/atoms/ButtonUpload/button-upload.stories.tsx +137 -0
  21. package/src/components/atoms/ButtonUpload/button-upload.tsx +304 -0
  22. package/src/components/atoms/ButtonUpload/index.ts +1 -0
  23. package/src/components/atoms/Calendar/calendar.stories.tsx +51 -0
  24. package/src/components/atoms/Calendar/calendar.test.tsx +41 -0
  25. package/src/components/atoms/Calendar/calendar.tsx +107 -0
  26. package/src/components/atoms/Calendar/index.ts +1 -0
  27. package/src/components/atoms/CheckIcon/check-icon.stories.tsx +38 -0
  28. package/src/components/atoms/CheckIcon/check-icon.test.tsx +270 -0
  29. package/src/components/atoms/CheckIcon/check-icon.tsx +141 -0
  30. package/src/components/atoms/CheckIcon/index.ts +1 -0
  31. package/src/components/atoms/Checkbox/checkbox.stories.tsx +133 -0
  32. package/src/components/atoms/Checkbox/checkbox.test.tsx +70 -0
  33. package/src/components/atoms/Checkbox/checkbox.tsx +31 -0
  34. package/src/components/atoms/Checkbox/index.ts +1 -0
  35. package/src/components/atoms/Flex/flex.stories.tsx +33 -0
  36. package/src/components/atoms/Flex/flex.test.tsx +47 -0
  37. package/src/components/atoms/Flex/flex.tsx +7 -0
  38. package/src/components/atoms/Flex/index.ts +1 -0
  39. package/src/components/atoms/Grid/grid.stories.tsx +33 -0
  40. package/src/components/atoms/Grid/grid.test.tsx +47 -0
  41. package/src/components/atoms/Grid/grid.tsx +7 -0
  42. package/src/components/atoms/Grid/index.ts +1 -0
  43. package/src/components/atoms/Icon/icon.stories.tsx +169 -0
  44. package/src/components/atoms/Icon/icon.test.tsx +272 -0
  45. package/src/components/atoms/Icon/icon.tsx +119 -0
  46. package/src/components/atoms/Icon/index.ts +1 -0
  47. package/src/components/atoms/Input/index.ts +1 -0
  48. package/src/components/atoms/Input/input.stories.tsx +704 -0
  49. package/src/components/atoms/Input/input.test.tsx +86 -0
  50. package/src/components/atoms/Input/input.tsx +161 -0
  51. package/src/components/atoms/InputMoney/index.ts +2 -0
  52. package/src/components/atoms/InputMoney/input-money.stories.tsx +240 -0
  53. package/src/components/atoms/InputMoney/input-money.test.tsx +98 -0
  54. package/src/components/atoms/InputMoney/input-money.tsx +254 -0
  55. package/src/components/atoms/InputPhone/index.ts +2 -0
  56. package/src/components/atoms/InputPhone/input-phone.stories.tsx +447 -0
  57. package/src/components/atoms/InputPhone/input-phone.test.tsx +148 -0
  58. package/src/components/atoms/InputPhone/input-phone.tsx +267 -0
  59. package/src/components/atoms/InputSearch/index.ts +2 -0
  60. package/src/components/atoms/InputSearch/input-search.stories.tsx +360 -0
  61. package/src/components/atoms/InputSearch/input-search.test.tsx +239 -0
  62. package/src/components/atoms/InputSearch/input-search.tsx +210 -0
  63. package/src/components/atoms/InputUpload/index.ts +1 -0
  64. package/src/components/atoms/InputUpload/input-upload.stories.tsx +229 -0
  65. package/src/components/atoms/InputUpload/input-upload.test.tsx +556 -0
  66. package/src/components/atoms/InputUpload/input-upload.tsx +434 -0
  67. package/src/components/atoms/InputWithButton/index.ts +2 -0
  68. package/src/components/atoms/InputWithButton/input-with-button.stories.tsx +503 -0
  69. package/src/components/atoms/InputWithButton/input-with-button.test.tsx +128 -0
  70. package/src/components/atoms/InputWithButton/input-with-button.tsx +170 -0
  71. package/src/components/atoms/Label/index.ts +1 -0
  72. package/src/components/atoms/Label/label.stories.tsx +90 -0
  73. package/src/components/atoms/Label/label.test.tsx +59 -0
  74. package/src/components/atoms/Label/label.tsx +43 -0
  75. package/src/components/atoms/Progress/index.ts +1 -0
  76. package/src/components/atoms/Progress/progress.stories.tsx +30 -0
  77. package/src/components/atoms/Progress/progress.test.tsx +63 -0
  78. package/src/components/atoms/Progress/progress.tsx +32 -0
  79. package/src/components/atoms/RenderCondition/index.ts +1 -0
  80. package/src/components/atoms/RenderCondition/render-condition.stories.tsx +28 -0
  81. package/src/components/atoms/RenderCondition/render-condition.test.tsx +27 -0
  82. package/src/components/atoms/RenderCondition/render-condition.tsx +9 -0
  83. package/src/components/atoms/RichTextEditor/index.ts +1 -0
  84. package/src/components/atoms/RichTextEditor/rich-text-editor.stories.tsx +214 -0
  85. package/src/components/atoms/RichTextEditor/rich-text-editor.test.tsx +442 -0
  86. package/src/components/atoms/RichTextEditor/rich-text-editor.tsx +202 -0
  87. package/src/components/atoms/Separator/index.ts +1 -0
  88. package/src/components/atoms/Separator/separator.stories.tsx +117 -0
  89. package/src/components/atoms/Separator/separator.test.tsx +50 -0
  90. package/src/components/atoms/Separator/separator.tsx +28 -0
  91. package/src/components/atoms/Skeleton/index.ts +1 -0
  92. package/src/components/atoms/Skeleton/skeleton.stories.tsx +84 -0
  93. package/src/components/atoms/Skeleton/skeleton.test.tsx +39 -0
  94. package/src/components/atoms/Skeleton/skeleton.tsx +14 -0
  95. package/src/components/atoms/Slider/index.ts +1 -0
  96. package/src/components/atoms/Slider/slider.stories.tsx +28 -0
  97. package/src/components/atoms/Slider/slider.test.tsx +90 -0
  98. package/src/components/atoms/Slider/slider.tsx +54 -0
  99. package/src/components/atoms/Sonner/index.ts +1 -0
  100. package/src/components/atoms/Sonner/sonner.css +39 -0
  101. package/src/components/atoms/Sonner/sonner.stories.tsx +261 -0
  102. package/src/components/atoms/Sonner/sonner.test.tsx +24 -0
  103. package/src/components/atoms/Sonner/sonner.tsx +13 -0
  104. package/src/components/atoms/Switch/index.ts +1 -0
  105. package/src/components/atoms/Switch/switch.stories.tsx +128 -0
  106. package/src/components/atoms/Switch/switch.test.tsx +70 -0
  107. package/src/components/atoms/Switch/switch.tsx +61 -0
  108. package/src/components/atoms/Textarea/index.ts +1 -0
  109. package/src/components/atoms/Textarea/textarea.stories.tsx +169 -0
  110. package/src/components/atoms/Textarea/textarea.test.tsx +56 -0
  111. package/src/components/atoms/Textarea/textarea.tsx +26 -0
  112. package/src/components/atoms/Toggle/index.ts +1 -0
  113. package/src/components/atoms/Toggle/toggle.stories.tsx +170 -0
  114. package/src/components/atoms/Toggle/toggle.test.tsx +62 -0
  115. package/src/components/atoms/Toggle/toggle.tsx +47 -0
  116. package/src/components/atoms/Typography/index.ts +1 -0
  117. package/src/components/atoms/Typography/typography.stories.tsx +95 -0
  118. package/src/components/atoms/Typography/typography.test.tsx +66 -0
  119. package/src/components/atoms/Typography/typography.tsx +63 -0
  120. package/src/components/atoms/UploadImageField/index.ts +1 -0
  121. package/src/components/atoms/UploadImageField/upload-image-field.stories.tsx +249 -0
  122. package/src/components/atoms/UploadImageField/upload-image-field.test.tsx +348 -0
  123. package/src/components/atoms/UploadImageField/upload-image-field.tsx +362 -0
  124. package/src/components/atoms/VideoPlayer/index.ts +1 -0
  125. package/src/components/atoms/VideoPlayer/video-player.stories.tsx +37 -0
  126. package/src/components/atoms/VideoPlayer/video-player.test.tsx +20 -0
  127. package/src/components/atoms/VideoPlayer/video-player.tsx +26 -0
  128. package/src/components/atoms/index.ts +31 -0
  129. package/src/components/icons/alert-circle.tsx +22 -0
  130. package/src/components/icons/align-center.tsx +22 -0
  131. package/src/components/icons/align-left.tsx +22 -0
  132. package/src/components/icons/annotation-dots.tsx +16 -0
  133. package/src/components/icons/annotation-question.tsx +15 -0
  134. package/src/components/icons/annotation.tsx +22 -0
  135. package/src/components/icons/announcement-01.tsx +15 -0
  136. package/src/components/icons/announcement-02.tsx +15 -0
  137. package/src/components/icons/apple-logo.tsx +9 -0
  138. package/src/components/icons/arrow-circle-broken-right.tsx +16 -0
  139. package/src/components/icons/arrow-down.tsx +9 -0
  140. package/src/components/icons/arrow-up.tsx +9 -0
  141. package/src/components/icons/at-sign.tsx +21 -0
  142. package/src/components/icons/award-01.tsx +15 -0
  143. package/src/components/icons/award-03.tsx +16 -0
  144. package/src/components/icons/bank-note-01.tsx +15 -0
  145. package/src/components/icons/bar-chart-square-02.tsx +9 -0
  146. package/src/components/icons/bell-01.tsx +9 -0
  147. package/src/components/icons/bell-04.tsx +16 -0
  148. package/src/components/icons/bold-01.tsx +22 -0
  149. package/src/components/icons/book-open-01.tsx +15 -0
  150. package/src/components/icons/brackets-ellipses.tsx +22 -0
  151. package/src/components/icons/briefcase-01.tsx +9 -0
  152. package/src/components/icons/brush-01.tsx +22 -0
  153. package/src/components/icons/building-02.tsx +9 -0
  154. package/src/components/icons/building-06.tsx +9 -0
  155. package/src/components/icons/calendar-minus-02.tsx +15 -0
  156. package/src/components/icons/calendar.tsx +9 -0
  157. package/src/components/icons/certificate-01.tsx +16 -0
  158. package/src/components/icons/chart-breakout-square.tsx +16 -0
  159. package/src/components/icons/check-circle-02.tsx +16 -0
  160. package/src/components/icons/check-circle.tsx +15 -0
  161. package/src/components/icons/check.tsx +21 -0
  162. package/src/components/icons/chevron-down-double.tsx +16 -0
  163. package/src/components/icons/chevron-down.tsx +9 -0
  164. package/src/components/icons/chevron-left-double.tsx +22 -0
  165. package/src/components/icons/chevron-left.tsx +16 -0
  166. package/src/components/icons/chevron-right-double.tsx +22 -0
  167. package/src/components/icons/chevron-right.tsx +16 -0
  168. package/src/components/icons/chevron-up-double.tsx +16 -0
  169. package/src/components/icons/clock-rewind.tsx +15 -0
  170. package/src/components/icons/clock-stopwatch.tsx +15 -0
  171. package/src/components/icons/coins-hand.tsx +15 -0
  172. package/src/components/icons/coins-stacked-01.tsx +15 -0
  173. package/src/components/icons/coins-stacked-02.tsx +15 -0
  174. package/src/components/icons/container.tsx +9 -0
  175. package/src/components/icons/copy-02.tsx +16 -0
  176. package/src/components/icons/copy-04.tsx +21 -0
  177. package/src/components/icons/corner-down-right.tsx +9 -0
  178. package/src/components/icons/countries/br.tsx +20 -0
  179. package/src/components/icons/countries/es.tsx +19 -0
  180. package/src/components/icons/countries/index.ts +3 -0
  181. package/src/components/icons/countries/us.tsx +21 -0
  182. package/src/components/icons/dataflow-03.tsx +15 -0
  183. package/src/components/icons/dotpoints-01.tsx +22 -0
  184. package/src/components/icons/dots-vertical.tsx +35 -0
  185. package/src/components/icons/download-03.tsx +16 -0
  186. package/src/components/icons/download-cloud-02.tsx +15 -0
  187. package/src/components/icons/drag.tsx +14 -0
  188. package/src/components/icons/dropper.tsx +21 -0
  189. package/src/components/icons/edit-01.tsx +15 -0
  190. package/src/components/icons/edit-02.tsx +9 -0
  191. package/src/components/icons/edit-03.tsx +23 -0
  192. package/src/components/icons/eye.tsx +22 -0
  193. package/src/components/icons/face-frown.tsx +15 -0
  194. package/src/components/icons/face-happy.tsx +15 -0
  195. package/src/components/icons/file-06.tsx +15 -0
  196. package/src/components/icons/file-attachment-04.tsx +15 -0
  197. package/src/components/icons/file-download-02.tsx +16 -0
  198. package/src/components/icons/file-plus-02.tsx +16 -0
  199. package/src/components/icons/file-search-01.tsx +22 -0
  200. package/src/components/icons/file-search-03.tsx +15 -0
  201. package/src/components/icons/filter-lines.tsx +21 -0
  202. package/src/components/icons/first-category.tsx +16 -0
  203. package/src/components/icons/first-stage.tsx +19 -0
  204. package/src/components/icons/folder.tsx +15 -0
  205. package/src/components/icons/google.tsx +12 -0
  206. package/src/components/icons/graduation-hat-02.tsx +15 -0
  207. package/src/components/icons/grid-01.tsx +36 -0
  208. package/src/components/icons/help-circle.tsx +16 -0
  209. package/src/components/icons/help-square.tsx +16 -0
  210. package/src/components/icons/home-line.tsx +21 -0
  211. package/src/components/icons/icons.stories.tsx +199 -0
  212. package/src/components/icons/index.ts +140 -0
  213. package/src/components/icons/info-circle.tsx +15 -0
  214. package/src/components/icons/italic-01.tsx +22 -0
  215. package/src/components/icons/last-category.tsx +11 -0
  216. package/src/components/icons/last-stage.tsx +19 -0
  217. package/src/components/icons/layout-alt-04.tsx +9 -0
  218. package/src/components/icons/lightbulb-02.tsx +16 -0
  219. package/src/components/icons/link-01.tsx +16 -0
  220. package/src/components/icons/link-broken-01.tsx +16 -0
  221. package/src/components/icons/linkedin-logo.tsx +17 -0
  222. package/src/components/icons/lock-01.tsx +21 -0
  223. package/src/components/icons/log-out-01.tsx +9 -0
  224. package/src/components/icons/mail-01.tsx +16 -0
  225. package/src/components/icons/marker-pin-02.tsx +10 -0
  226. package/src/components/icons/menu-01.tsx +9 -0
  227. package/src/components/icons/middle-category.tsx +10 -0
  228. package/src/components/icons/middle-stage.tsx +19 -0
  229. package/src/components/icons/ms-outlook.tsx +47 -0
  230. package/src/components/icons/paragraph-spacing.tsx +15 -0
  231. package/src/components/icons/phone-01.tsx +21 -0
  232. package/src/components/icons/pie-chart-02.tsx +22 -0
  233. package/src/components/icons/plus-circle.tsx +15 -0
  234. package/src/components/icons/portal-logo.tsx +76 -0
  235. package/src/components/icons/presentation-chart-02.tsx +14 -0
  236. package/src/components/icons/route.tsx +22 -0
  237. package/src/components/icons/save-01.tsx +15 -0
  238. package/src/components/icons/search-lg.tsx +15 -0
  239. package/src/components/icons/search-sm.tsx +9 -0
  240. package/src/components/icons/send-03.tsx +15 -0
  241. package/src/components/icons/settings-01.tsx +17 -0
  242. package/src/components/icons/settings-03.tsx +14 -0
  243. package/src/components/icons/share-05.tsx +15 -0
  244. package/src/components/icons/share-06.tsx +15 -0
  245. package/src/components/icons/slash-circle-01.tsx +9 -0
  246. package/src/components/icons/star-01.tsx +9 -0
  247. package/src/components/icons/step-icon-active.tsx +11 -0
  248. package/src/components/icons/step-icon-checked.tsx +10 -0
  249. package/src/components/icons/step-icon-default.tsx +11 -0
  250. package/src/components/icons/switch-horizontal-01.tsx +9 -0
  251. package/src/components/icons/table-01.tsx +15 -0
  252. package/src/components/icons/tag-01.tsx +15 -0
  253. package/src/components/icons/tag-03.tsx +15 -0
  254. package/src/components/icons/tool-02.tsx +14 -0
  255. package/src/components/icons/trash-01.tsx +15 -0
  256. package/src/components/icons/underline-01.tsx +22 -0
  257. package/src/components/icons/upload-cloud-02.tsx +15 -0
  258. package/src/components/icons/user-01.tsx +9 -0
  259. package/src/components/icons/user-03.tsx +9 -0
  260. package/src/components/icons/user-check-01.tsx +14 -0
  261. package/src/components/icons/user-circle.tsx +14 -0
  262. package/src/components/icons/user-edit.tsx +16 -0
  263. package/src/components/icons/user-minus-02.tsx +15 -0
  264. package/src/components/icons/user-plus-01.tsx +22 -0
  265. package/src/components/icons/user-plus-02.tsx +15 -0
  266. package/src/components/icons/user-square.tsx +16 -0
  267. package/src/components/icons/users-01.tsx +14 -0
  268. package/src/components/icons/users-plus-01.tsx +21 -0
  269. package/src/components/icons/users-plus.tsx +16 -0
  270. package/src/components/icons/vertical-drag.tsx +21 -0
  271. package/src/components/icons/x-circle.tsx +15 -0
  272. package/src/components/icons/x-close.tsx +9 -0
  273. package/src/components/icons/zap-fast.tsx +16 -0
  274. package/src/components/icons/zap.tsx +9 -0
  275. package/src/components/index.ts +4 -0
  276. package/src/components/molecules/Accordion/accordion.stories.tsx +81 -0
  277. package/src/components/molecules/Accordion/accordion.test.tsx +91 -0
  278. package/src/components/molecules/Accordion/accordion.tsx +65 -0
  279. package/src/components/molecules/Accordion/index.ts +1 -0
  280. package/src/components/molecules/Alert/alert.stories.tsx +75 -0
  281. package/src/components/molecules/Alert/alert.test.tsx +58 -0
  282. package/src/components/molecules/Alert/alert.tsx +67 -0
  283. package/src/components/molecules/Alert/index.ts +1 -0
  284. package/src/components/molecules/AlertDialog/alert-dialog.stories.tsx +55 -0
  285. package/src/components/molecules/AlertDialog/alert-dialog.test.tsx +34 -0
  286. package/src/components/molecules/AlertDialog/alert-dialog.tsx +172 -0
  287. package/src/components/molecules/AlertDialog/index.ts +1 -0
  288. package/src/components/molecules/Avatar/avatar.stories.tsx +98 -0
  289. package/src/components/molecules/Avatar/avatar.test.tsx +55 -0
  290. package/src/components/molecules/Avatar/avatar.tsx +55 -0
  291. package/src/components/molecules/Avatar/index.ts +1 -0
  292. package/src/components/molecules/Breadcrumb/breadcrumb.stories.tsx +125 -0
  293. package/src/components/molecules/Breadcrumb/breadcrumb.test.tsx +118 -0
  294. package/src/components/molecules/Breadcrumb/breadcrumb.tsx +120 -0
  295. package/src/components/molecules/Breadcrumb/index.ts +1 -0
  296. package/src/components/molecules/Card/card.stories.tsx +109 -0
  297. package/src/components/molecules/Card/card.test.tsx +103 -0
  298. package/src/components/molecules/Card/card.tsx +78 -0
  299. package/src/components/molecules/Card/index.ts +1 -0
  300. package/src/components/molecules/Collapsible/collapsible.stories.tsx +28 -0
  301. package/src/components/molecules/Collapsible/collapsible.test.tsx +36 -0
  302. package/src/components/molecules/Collapsible/collapsible.tsx +31 -0
  303. package/src/components/molecules/Collapsible/index.ts +1 -0
  304. package/src/components/molecules/ColorPicker/color-picker.stories.tsx +40 -0
  305. package/src/components/molecules/ColorPicker/color-picker.tsx +106 -0
  306. package/src/components/molecules/ColorPicker/index.ts +1 -0
  307. package/src/components/molecules/ColorScale/color-scale.stories.tsx +31 -0
  308. package/src/components/molecules/ColorScale/color-scale.tsx +74 -0
  309. package/src/components/molecules/ColorScale/index.ts +1 -0
  310. package/src/components/molecules/Command/command.stories.tsx +71 -0
  311. package/src/components/molecules/Command/command.test.tsx +50 -0
  312. package/src/components/molecules/Command/command.tsx +177 -0
  313. package/src/components/molecules/Command/index.ts +1 -0
  314. package/src/components/molecules/ContextMenu/context-menu.stories.tsx +69 -0
  315. package/src/components/molecules/ContextMenu/context-menu.test.tsx +25 -0
  316. package/src/components/molecules/ContextMenu/context-menu.tsx +259 -0
  317. package/src/components/molecules/ContextMenu/index.ts +1 -0
  318. package/src/components/molecules/DatePicker/date-picker.stories.tsx +204 -0
  319. package/src/components/molecules/DatePicker/date-picker.test.tsx +27 -0
  320. package/src/components/molecules/DatePicker/date-picker.tsx +486 -0
  321. package/src/components/molecules/DatePicker/index.ts +1 -0
  322. package/src/components/molecules/Dialog/dialog.stories.tsx +48 -0
  323. package/src/components/molecules/Dialog/dialog.test.tsx +51 -0
  324. package/src/components/molecules/Dialog/dialog.tsx +150 -0
  325. package/src/components/molecules/Dialog/index.ts +1 -0
  326. package/src/components/molecules/Drawer/drawer.stories.tsx +182 -0
  327. package/src/components/molecules/Drawer/drawer.test.tsx +100 -0
  328. package/src/components/molecules/Drawer/drawer.tsx +206 -0
  329. package/src/components/molecules/Drawer/index.ts +1 -0
  330. package/src/components/molecules/Dropdown/dropdown-async.stories.tsx +15 -0
  331. package/src/components/molecules/Dropdown/dropdown.stories.tsx +112 -0
  332. package/src/components/molecules/Dropdown/dropdown.test.tsx +128 -0
  333. package/src/components/molecules/Dropdown/dropdown.tsx +322 -0
  334. package/src/components/molecules/Dropdown/index.ts +1 -0
  335. package/src/components/molecules/DropdownMenu/dropdown-menu.stories.tsx +154 -0
  336. package/src/components/molecules/DropdownMenu/dropdown-menu.test.tsx +163 -0
  337. package/src/components/molecules/DropdownMenu/dropdown-menu.tsx +313 -0
  338. package/src/components/molecules/DropdownMenu/index.ts +1 -0
  339. package/src/components/molecules/HoverCard/hover-card.stories.tsx +48 -0
  340. package/src/components/molecules/HoverCard/hover-card.test.tsx +42 -0
  341. package/src/components/molecules/HoverCard/hover-card.tsx +44 -0
  342. package/src/components/molecules/HoverCard/index.ts +1 -0
  343. package/src/components/molecules/InputOTP/index.ts +1 -0
  344. package/src/components/molecules/InputOTP/input-otp.stories.tsx +52 -0
  345. package/src/components/molecules/InputOTP/input-otp.test.tsx +28 -0
  346. package/src/components/molecules/InputOTP/input-otp.tsx +76 -0
  347. package/src/components/molecules/Menubar/index.ts +1 -0
  348. package/src/components/molecules/Menubar/menubar.stories.tsx +113 -0
  349. package/src/components/molecules/Menubar/menubar.test.tsx +42 -0
  350. package/src/components/molecules/Menubar/menubar.tsx +314 -0
  351. package/src/components/molecules/NavigationMenu/index.ts +1 -0
  352. package/src/components/molecules/NavigationMenu/navigation-menu.stories.tsx +143 -0
  353. package/src/components/molecules/NavigationMenu/navigation-menu.test.tsx +69 -0
  354. package/src/components/molecules/NavigationMenu/navigation-menu.tsx +174 -0
  355. package/src/components/molecules/PDFViewer/index.ts +1 -0
  356. package/src/components/molecules/PDFViewer/pdf-viewer.stories.tsx +34 -0
  357. package/src/components/molecules/PDFViewer/pdf-viewer.test.tsx +26 -0
  358. package/src/components/molecules/PDFViewer/pdf-viewer.tsx +358 -0
  359. package/src/components/molecules/Pagination/index.ts +1 -0
  360. package/src/components/molecules/Pagination/pagination.stories.tsx +193 -0
  361. package/src/components/molecules/Pagination/pagination.test.tsx +448 -0
  362. package/src/components/molecules/Pagination/pagination.tsx +206 -0
  363. package/src/components/molecules/PaginationDotGroup/index.ts +1 -0
  364. package/src/components/molecules/PaginationDotGroup/pagination-dot-group.stories.tsx +211 -0
  365. package/src/components/molecules/PaginationDotGroup/pagination-dot-group.test.tsx +385 -0
  366. package/src/components/molecules/PaginationDotGroup/pagination-dot-group.tsx +119 -0
  367. package/src/components/molecules/Popover/index.ts +1 -0
  368. package/src/components/molecules/Popover/popover-menu.stories.tsx +27 -0
  369. package/src/components/molecules/Popover/popover.test.tsx +50 -0
  370. package/src/components/molecules/Popover/popover.tsx +38 -0
  371. package/src/components/molecules/ProgressSteps/index.ts +1 -0
  372. package/src/components/molecules/ProgressSteps/progress-steps.stories.tsx +36 -0
  373. package/src/components/molecules/ProgressSteps/progress-steps.test.tsx +470 -0
  374. package/src/components/molecules/ProgressSteps/progress-steps.tsx +140 -0
  375. package/src/components/molecules/RadioGroup/index.ts +1 -0
  376. package/src/components/molecules/RadioGroup/radio-group.stories.tsx +42 -0
  377. package/src/components/molecules/RadioGroup/radio-group.test.tsx +22 -0
  378. package/src/components/molecules/RadioGroup/radio-group.tsx +55 -0
  379. package/src/components/molecules/Resizable/index.ts +1 -0
  380. package/src/components/molecules/Resizable/resizable.stories.tsx +52 -0
  381. package/src/components/molecules/Resizable/resizable.test.tsx +22 -0
  382. package/src/components/molecules/Resizable/resizable.tsx +55 -0
  383. package/src/components/molecules/ScrollArea/index.ts +1 -0
  384. package/src/components/molecules/ScrollArea/scroll-area.stories.tsx +93 -0
  385. package/src/components/molecules/ScrollArea/scroll-area.test.tsx +28 -0
  386. package/src/components/molecules/ScrollArea/scroll-area.tsx +57 -0
  387. package/src/components/molecules/Select/index.ts +1 -0
  388. package/src/components/molecules/Select/select.stories.tsx +63 -0
  389. package/src/components/molecules/Select/select.test.tsx +80 -0
  390. package/src/components/molecules/Select/select.tsx +172 -0
  391. package/src/components/molecules/Sheet/index.ts +1 -0
  392. package/src/components/molecules/Sheet/sheet.stories.tsx +141 -0
  393. package/src/components/molecules/Sheet/sheet.test.tsx +70 -0
  394. package/src/components/molecules/Sheet/sheet.tsx +133 -0
  395. package/src/components/molecules/Tabs/index.ts +1 -0
  396. package/src/components/molecules/Tabs/tabs.stories.tsx +222 -0
  397. package/src/components/molecules/Tabs/tabs.test.tsx +113 -0
  398. package/src/components/molecules/Tabs/tabs.tsx +102 -0
  399. package/src/components/molecules/ToggleGroup/index.ts +1 -0
  400. package/src/components/molecules/ToggleGroup/toggle-group.stories.tsx +117 -0
  401. package/src/components/molecules/ToggleGroup/toggle-group.test.tsx +100 -0
  402. package/src/components/molecules/ToggleGroup/toggle-group.tsx +70 -0
  403. package/src/components/molecules/Tooltip/index.ts +1 -0
  404. package/src/components/molecules/Tooltip/tooltip.stories.tsx +133 -0
  405. package/src/components/molecules/Tooltip/tooltip.test.tsx +58 -0
  406. package/src/components/molecules/Tooltip/tooltip.tsx +58 -0
  407. package/src/components/molecules/index.ts +33 -0
  408. package/src/components/organisms/Carousel/carousel.stories.tsx +94 -0
  409. package/src/components/organisms/Carousel/carousel.test.tsx +24 -0
  410. package/src/components/organisms/Carousel/carousel.tsx +383 -0
  411. package/src/components/organisms/Carousel/index.ts +1 -0
  412. package/src/components/organisms/Chart/chart.stories.tsx +102 -0
  413. package/src/components/organisms/Chart/chart.test.tsx +105 -0
  414. package/src/components/organisms/Chart/chart.tsx +294 -0
  415. package/src/components/organisms/Chart/index.ts +1 -0
  416. package/src/components/organisms/FileUpload/FilePreview/file-preview.tsx +55 -0
  417. package/src/components/organisms/FileUpload/FilePreview/index.ts +1 -0
  418. package/src/components/organisms/FileUpload/file-upload.stories.tsx +20 -0
  419. package/src/components/organisms/FileUpload/file-upload.test.tsx +59 -0
  420. package/src/components/organisms/FileUpload/file-upload.tsx +175 -0
  421. package/src/components/organisms/FileUpload/file.d.ts +21 -0
  422. package/src/components/organisms/FileUpload/index.ts +1 -0
  423. package/src/components/organisms/Form/form.stories.tsx +155 -0
  424. package/src/components/organisms/Form/form.test.tsx +49 -0
  425. package/src/components/organisms/Form/form.tsx +133 -0
  426. package/src/components/organisms/Form/index.ts +1 -0
  427. package/src/components/organisms/Sidebar/index.ts +1 -0
  428. package/src/components/organisms/Sidebar/sidebar.stories.tsx +86 -0
  429. package/src/components/organisms/Sidebar/sidebar.test.tsx +101 -0
  430. package/src/components/organisms/Sidebar/sidebar.tsx +666 -0
  431. package/src/components/organisms/Table/index.ts +1 -0
  432. package/src/components/organisms/Table/table.stories.tsx +86 -0
  433. package/src/components/organisms/Table/table.test.tsx +42 -0
  434. package/src/components/organisms/Table/table.tsx +120 -0
  435. package/src/components/organisms/index.ts +6 -0
  436. package/src/constants/brazilian-states.ts +29 -0
  437. package/src/constants/index.ts +1 -0
  438. package/src/hooks/index.ts +10 -0
  439. package/src/hooks/useEditorActiveMarks.ts +63 -0
  440. package/src/hooks/useForm.ts +8 -0
  441. package/src/hooks/useFormContext.ts +7 -0
  442. package/src/hooks/useFormField.ts +41 -0
  443. package/src/hooks/useMobile.ts +61 -0
  444. package/src/hooks/useOnToggle.ts +28 -0
  445. package/src/hooks/usePDFNavigation.ts +41 -0
  446. package/src/hooks/usePDFZoom.ts +35 -0
  447. package/src/hooks/useSidebar.ts +23 -0
  448. package/src/hooks/useToast.tsx +63 -0
  449. package/src/index.css +73 -0
  450. package/src/main.ts +6 -0
  451. package/src/theme.css +388 -0
  452. package/src/utils/api/api.test.ts +64 -0
  453. package/src/utils/api/api.ts +34 -0
  454. package/src/utils/api/index.ts +1 -0
  455. package/src/utils/array/array.test.ts +160 -0
  456. package/src/utils/array/array.ts +43 -0
  457. package/src/utils/array/index.ts +1 -0
  458. package/src/utils/clipboard/clipboard.test.ts +218 -0
  459. package/src/utils/clipboard/clipboard.ts +40 -0
  460. package/src/utils/clipboard/index.ts +1 -0
  461. package/src/utils/cn/cn.test.ts +43 -0
  462. package/src/utils/cn/cn.ts +6 -0
  463. package/src/utils/cn/index.ts +1 -0
  464. package/src/utils/color-utils/color-utils.test.ts +46 -0
  465. package/src/utils/color-utils/color-utils.ts +97 -0
  466. package/src/utils/color-utils/index.ts +1 -0
  467. package/src/utils/countries/countries.ts +69 -0
  468. package/src/utils/countries/index.ts +1 -0
  469. package/src/utils/currency/currency.test.ts +114 -0
  470. package/src/utils/currency/currency.ts +134 -0
  471. package/src/utils/currency/index.ts +1 -0
  472. package/src/utils/date/date.test.ts +167 -0
  473. package/src/utils/date/date.ts +83 -0
  474. package/src/utils/date/index.ts +1 -0
  475. package/src/utils/file/file.ts +45 -0
  476. package/src/utils/file/index.ts +1 -0
  477. package/src/utils/get-initials/get-initials.test.ts +40 -0
  478. package/src/utils/get-initials/get-initials.ts +13 -0
  479. package/src/utils/get-initials/index.ts +1 -0
  480. package/src/utils/index.ts +14 -0
  481. package/src/utils/masks/index.ts +1 -0
  482. package/src/utils/masks/masks.ts +180 -0
  483. package/src/utils/render-highlighted-text/index.ts +1 -0
  484. package/src/utils/render-highlighted-text/render-highlighted-text.tsx +25 -0
  485. package/src/utils/string/index.ts +1 -0
  486. package/src/utils/string/string.test.ts +171 -0
  487. package/src/utils/string/string.ts +155 -0
  488. package/src/utils/video/index.ts +1 -0
  489. package/src/utils/video/video.ts +9 -0
  490. package/src/vite-env.d.ts +3 -0
@@ -0,0 +1,503 @@
1
+ import { useState } from 'react';
2
+
3
+ import { InputWithButton } from './input-with-button';
4
+
5
+ import type { Meta, StoryObj } from '@storybook/react';
6
+
7
+ import { PlusCircle } from '@/components';
8
+ import { MASKS } from '@/utils';
9
+
10
+ const meta: Meta<typeof InputWithButton> = {
11
+ title: 'Components/Data Entry/InputWithButton',
12
+ component: InputWithButton,
13
+ tags: [ 'autodocs' ],
14
+ parameters: {
15
+ layout: 'centered',
16
+ docs: {
17
+ description: {
18
+ component: 'A flexible input component with an integrated button, supporting masks, various states, sizes, and custom actions. Perfect for search inputs, form submissions, and interactive data entry.',
19
+ },
20
+ },
21
+ },
22
+ argTypes: {
23
+ 'buttonText': {
24
+ control: { type: 'text' },
25
+ description: 'Text displayed on the button',
26
+ },
27
+ 'onButtonClick': {
28
+ action: 'button clicked',
29
+ description: 'Callback triggered when the button is clicked',
30
+ },
31
+ 'buttonLoading': {
32
+ control: { type: 'boolean' },
33
+ description: 'Whether the button is in a loading state',
34
+ },
35
+ 'buttonDisabled': {
36
+ control: { type: 'boolean' },
37
+ description: 'Whether the button is disabled',
38
+ },
39
+ 'error': {
40
+ control: { type: 'text' },
41
+ description: 'Error message to display below the input field',
42
+ },
43
+ 'success': {
44
+ control: { type: 'boolean' },
45
+ description: 'Success state',
46
+ },
47
+ 'size': {
48
+ control: { type: 'select' },
49
+ options: [ 'sm', 'md', 'lg' ],
50
+ description: 'Size of the input and button',
51
+ },
52
+ 'mask': {
53
+ control: { type: 'text' },
54
+ description: 'Input mask pattern (use MASKS from utils)',
55
+ },
56
+ 'loading': {
57
+ control: { type: 'boolean' },
58
+ description: 'Whether the input is in a loading state',
59
+ },
60
+ 'disabled': {
61
+ control: { type: 'boolean' },
62
+ description: 'Disabled state',
63
+ },
64
+ 'placeholder': {
65
+ control: { type: 'text' },
66
+ description: 'Placeholder text',
67
+ },
68
+ 'data-testid': {
69
+ control: { type: 'text' },
70
+ description: 'Test identifier',
71
+ },
72
+ },
73
+ };
74
+
75
+ export default meta;
76
+
77
+ type Story = StoryObj<typeof meta>;
78
+
79
+ const SearchExample = () => {
80
+ const [ searchTerm, setSearchTerm ] = useState('');
81
+ const [ isSearching, setIsSearching ] = useState(false);
82
+
83
+ const handleSearch = () => {
84
+ if (!searchTerm.trim()) return;
85
+
86
+ setIsSearching(true);
87
+ setTimeout(() => {
88
+ setIsSearching(false);
89
+ alert(`Searching for: ${searchTerm}`);
90
+ }, 2000);
91
+ };
92
+
93
+ return (
94
+ <div className="w-80 space-y-4 p-6 border rounded-lg">
95
+ <h3 className="text-lg font-semibold mb-4">Search Example</h3>
96
+
97
+ <InputWithButton
98
+ placeholder="Enter product name..."
99
+ value={searchTerm}
100
+ onChange={(e) => setSearchTerm(e.target.value)}
101
+ buttonText="Search"
102
+ onButtonClick={handleSearch}
103
+ buttonLoading={isSearching}
104
+ />
105
+
106
+ <div className="text-sm text-gray-600">
107
+ <p>Current search term: {searchTerm || 'None'}</p>
108
+ </div>
109
+ </div>
110
+ );
111
+ };
112
+
113
+ const FormSubmissionExample = () => {
114
+ const [ email, setEmail ] = useState('');
115
+ const [ isSubmitting, setIsSubmitting ] = useState(false);
116
+ const [ hasError, setHasError ] = useState(false);
117
+
118
+ const handleSubmit = () => {
119
+ if (!email.includes('@')) {
120
+ setHasError(true);
121
+ return;
122
+ }
123
+
124
+ setIsSubmitting(true);
125
+ setHasError(false);
126
+
127
+ setTimeout(() => {
128
+ setIsSubmitting(false);
129
+ alert(`Newsletter subscription successful for: ${email}`);
130
+ setEmail('');
131
+ }, 2000);
132
+ };
133
+
134
+ return (
135
+ <div className="w-80 space-y-4 p-6 border rounded-lg">
136
+ <h3 className="text-lg font-semibold mb-4">Newsletter Subscription</h3>
137
+
138
+ <InputWithButton
139
+ placeholder="your@email.com"
140
+ value={email}
141
+ onChange={(e) => {
142
+ setEmail(e.target.value);
143
+ setHasError(false);
144
+ }}
145
+ buttonText="Subscribe"
146
+ onButtonClick={handleSubmit}
147
+ buttonLoading={isSubmitting}
148
+ error={hasError ? 'Please enter a valid email address' : undefined}
149
+ />
150
+ </div>
151
+ );
152
+ };
153
+
154
+ const ValidationExample = () => {
155
+ const [ cpf, setCpf ] = useState('');
156
+ const [ isChecking, setIsChecking ] = useState(false);
157
+ const [ isValid, setIsValid ] = useState<boolean | null>(null);
158
+
159
+ const handleValidate = () => {
160
+ if (!cpf) return;
161
+
162
+ setIsChecking(true);
163
+ setTimeout(() => {
164
+ setIsChecking(false);
165
+ const isValidCPF = cpf.replace(/\D/g, '').length === 11;
166
+ setIsValid(isValidCPF);
167
+ }, 1500);
168
+ };
169
+
170
+ return (
171
+ <div className="w-80 space-y-4 p-6 border rounded-lg">
172
+ <h3 className="text-lg font-semibold mb-4">CPF Validation</h3>
173
+
174
+ <InputWithButton
175
+ mask={MASKS.CPF}
176
+ placeholder="000.000.000-00"
177
+ value={cpf}
178
+ onChange={(e) => {
179
+ setCpf(e.target.value);
180
+ setIsValid(null);
181
+ }}
182
+ buttonText="Validate"
183
+ onButtonClick={handleValidate}
184
+ buttonLoading={isChecking}
185
+ success={isValid === true}
186
+ error={isValid === false ? 'Invalid CPF number' : undefined}
187
+ />
188
+ </div>
189
+ );
190
+ };
191
+
192
+ export const AllSizes: Story = {
193
+ name: 'All Sizes Showcase',
194
+ render: () => (
195
+ <div className="space-y-6">
196
+ <div>
197
+ <h4 className="text-sm font-medium text-gray-700 mb-2">Small</h4>
198
+ <div className="space-y-2">
199
+ <InputWithButton size="sm" placeholder="Small input" buttonText="Go" />
200
+ <InputWithButton size="sm" placeholder="Search..." buttonText="Search" />
201
+ </div>
202
+ </div>
203
+
204
+ <div>
205
+ <h4 className="text-sm font-medium text-gray-700 mb-2">Medium</h4>
206
+ <div className="space-y-2">
207
+ <InputWithButton size="md" placeholder="Medium input" buttonText="Submit" />
208
+ <InputWithButton size="md" placeholder="Enter URL..." buttonText="Visit" />
209
+ </div>
210
+ </div>
211
+
212
+ <div>
213
+ <h4 className="text-sm font-medium text-gray-700 mb-2">Large</h4>
214
+ <div className="space-y-2">
215
+ <InputWithButton size="lg" placeholder="Large input" buttonText="Send" />
216
+ <InputWithButton size="lg" placeholder="Enter code..." buttonText="Verify" />
217
+ </div>
218
+ </div>
219
+ </div>
220
+ ),
221
+ parameters: {
222
+ docs: {
223
+ description: {
224
+ story: 'Comparison of all available sizes with different button texts.',
225
+ },
226
+ },
227
+ },
228
+ };
229
+
230
+ export const AllStates: Story = {
231
+ name: 'All States Showcase',
232
+ render: () => (
233
+ <div className="space-y-4">
234
+ <div>
235
+ <h4 className="text-sm font-medium text-gray-700 mb-2">Normal</h4>
236
+ <InputWithButton placeholder="Normal state" buttonText="Action" />
237
+ </div>
238
+
239
+ <div>
240
+ <h4 className="text-sm font-medium text-gray-700 mb-2">Error</h4>
241
+ <InputWithButton
242
+ error="Invalid input"
243
+ placeholder="Error state"
244
+ buttonText="Try Again"
245
+ />
246
+ </div>
247
+
248
+ <div>
249
+ <h4 className="text-sm font-medium text-gray-700 mb-2">Success</h4>
250
+ <InputWithButton
251
+ success
252
+ placeholder="Success state"
253
+ buttonText="Success"
254
+ />
255
+ </div>
256
+
257
+ <div>
258
+ <h4 className="text-sm font-medium text-gray-700 mb-2">Loading</h4>
259
+ <InputWithButton
260
+ loading
261
+ placeholder="Loading state"
262
+ buttonText="Processing"
263
+ />
264
+ </div>
265
+
266
+ <div>
267
+ <h4 className="text-sm font-medium text-gray-700 mb-2">Button Loading</h4>
268
+ <InputWithButton
269
+ placeholder="Button loading"
270
+ buttonText="Submit"
271
+ buttonLoading
272
+ />
273
+ </div>
274
+
275
+ <div>
276
+ <h4 className="text-sm font-medium text-gray-700 mb-2">Disabled</h4>
277
+ <InputWithButton
278
+ disabled
279
+ placeholder="Disabled state"
280
+ buttonText="Disabled"
281
+ />
282
+ </div>
283
+ </div>
284
+ ),
285
+ parameters: {
286
+ docs: {
287
+ description: {
288
+ story: 'Showcase of all available states and their visual feedback.',
289
+ },
290
+ },
291
+ },
292
+ };
293
+
294
+ export const ButtonDisabled: Story = {
295
+ name: 'Button Disabled',
296
+ args: {
297
+ placeholder: 'Enter text...',
298
+ buttonText: 'Action',
299
+ buttonDisabled: true,
300
+ },
301
+ };
302
+
303
+ export const ButtonLoading: Story = {
304
+ name: 'Button Loading',
305
+ args: {
306
+ placeholder: 'Enter data...',
307
+ buttonText: 'Process',
308
+ buttonLoading: true,
309
+ },
310
+ };
311
+
312
+ export const Default: Story = {
313
+ args: {
314
+ placeholder: 'Enter text...',
315
+ buttonText: 'Action',
316
+ },
317
+ };
318
+
319
+ export const Disabled: Story = {
320
+ args: {
321
+ placeholder: 'Disabled input...',
322
+ buttonText: 'Action',
323
+ disabled: true,
324
+ },
325
+ };
326
+
327
+ export const FormSubmissionStory: Story = {
328
+ name: 'Form Submission Example',
329
+ render: () => <FormSubmissionExample />,
330
+ parameters: {
331
+ docs: {
332
+ description: {
333
+ story: 'A newsletter subscription form with validation and submission states.',
334
+ },
335
+ },
336
+ },
337
+ };
338
+
339
+ export const Large: Story = {
340
+ args: {
341
+ size: 'lg',
342
+ placeholder: 'Large input...',
343
+ buttonText: 'Send',
344
+ },
345
+ };
346
+
347
+ export const Loading: Story = {
348
+ args: {
349
+ placeholder: 'Processing...',
350
+ buttonText: 'Submit',
351
+ loading: true,
352
+ },
353
+ };
354
+
355
+ export const Medium: Story = {
356
+ args: {
357
+ size: 'md',
358
+ placeholder: 'Medium input...',
359
+ buttonText: 'Submit',
360
+ },
361
+ };
362
+
363
+ export const SearchExampleStory: Story = {
364
+ name: 'Search Example',
365
+ render: () => <SearchExample />,
366
+ parameters: {
367
+ docs: {
368
+ description: {
369
+ story: 'A complete search example with loading states and user feedback.',
370
+ },
371
+ },
372
+ },
373
+ };
374
+
375
+ export const Small: Story = {
376
+ args: {
377
+ size: 'sm',
378
+ placeholder: 'Small input...',
379
+ buttonText: 'Go',
380
+ },
381
+ };
382
+
383
+ export const ValidationStory: Story = {
384
+ name: 'Validation Example',
385
+ render: () => <ValidationExample />,
386
+ parameters: {
387
+ docs: {
388
+ description: {
389
+ story: 'CPF validation example with real-time feedback and success/error states.',
390
+ },
391
+ },
392
+ },
393
+ };
394
+
395
+ export const WithButtonIcon: Story = {
396
+ name: 'With Button Icon',
397
+ args: {
398
+ placeholder: 'Enter text...',
399
+ buttonText: 'Action',
400
+ buttonIcon: <PlusCircle />,
401
+ },
402
+ };
403
+
404
+ export const WithCEPMask: Story = {
405
+ name: 'With CEP Mask',
406
+ args: {
407
+ mask: MASKS.CEP,
408
+ placeholder: '00000-000',
409
+ buttonText: 'Find',
410
+ },
411
+ };
412
+
413
+ export const WithCPFMask: Story = {
414
+ name: 'With CPF Mask',
415
+ args: {
416
+ mask: MASKS.CPF,
417
+ placeholder: '000.000.000-00',
418
+ buttonText: 'Validate',
419
+ },
420
+ };
421
+
422
+ export const WithCreditCardMask: Story = {
423
+ name: 'With Credit Card Mask',
424
+ args: {
425
+ mask: MASKS.CREDIT_CARD,
426
+ placeholder: '0000 0000 0000 0000',
427
+ buttonText: 'Pay',
428
+ },
429
+ };
430
+
431
+ export const WithError: Story = {
432
+ name: 'With Error',
433
+ args: {
434
+ placeholder: 'Enter username',
435
+ buttonText: 'Check',
436
+ error: 'Username is already taken',
437
+ },
438
+ };
439
+
440
+ export const WithMasks: Story = {
441
+ name: 'With Masks Showcase',
442
+ render: () => (
443
+ <div className="space-y-4 w-80">
444
+ <div>
445
+ <label className="block text-sm font-medium text-gray-700 mb-1">CPF</label>
446
+ <InputWithButton
447
+ mask={MASKS.CPF}
448
+ placeholder="000.000.000-00"
449
+ buttonText="Validate"
450
+ />
451
+ </div>
452
+ <div>
453
+ <label className="block text-sm font-medium text-gray-700 mb-1">Phone</label>
454
+ <InputWithButton
455
+ mask={MASKS.PHONE_MOBILE}
456
+ placeholder="(11) 9 9999-9999"
457
+ buttonText="Call"
458
+ />
459
+ </div>
460
+ <div>
461
+ <label className="block text-sm font-medium text-gray-700 mb-1">CEP</label>
462
+ <InputWithButton
463
+ mask={MASKS.CEP}
464
+ placeholder="00000-000"
465
+ buttonText="Find"
466
+ />
467
+ </div>
468
+ <div>
469
+ <label className="block text-sm font-medium text-gray-700 mb-1">Credit Card</label>
470
+ <InputWithButton
471
+ mask={MASKS.CREDIT_CARD}
472
+ placeholder="0000 0000 0000 0000"
473
+ buttonText="Pay"
474
+ />
475
+ </div>
476
+ </div>
477
+ ),
478
+ parameters: {
479
+ docs: {
480
+ description: {
481
+ story: 'Input with button using common Brazilian masks.',
482
+ },
483
+ },
484
+ },
485
+ };
486
+
487
+ export const WithPhoneMask: Story = {
488
+ name: 'With Phone Mask',
489
+ args: {
490
+ mask: MASKS.PHONE_MOBILE,
491
+ placeholder: '(11) 9 9999-9999',
492
+ buttonText: 'Call',
493
+ },
494
+ };
495
+
496
+ export const WithSuccess: Story = {
497
+ name: 'With Success',
498
+ args: {
499
+ placeholder: 'Enter 6-digit code',
500
+ buttonText: 'Verify',
501
+ success: true,
502
+ },
503
+ };
@@ -0,0 +1,128 @@
1
+ import { render, screen, fireEvent } from '@testing-library/react';
2
+ import { describe, it, expect, vi } from 'vitest';
3
+
4
+ import { InputWithButton } from './input-with-button';
5
+
6
+ describe('<InputWithButton />', () => {
7
+ it('renders with default props', () => {
8
+ render(<InputWithButton data-testid="input-with-button" />);
9
+
10
+ const input = screen.getByTestId('input-with-button');
11
+ const button = screen.getByRole('button');
12
+
13
+ expect(input).toBeInTheDocument();
14
+ expect(button).toBeInTheDocument();
15
+ expect(button).toHaveTextContent('Ação');
16
+ });
17
+
18
+ it('renders with custom button text', () => {
19
+ render(<InputWithButton buttonText="Search" data-testid="input-with-button" />);
20
+
21
+ const button = screen.getByRole('button');
22
+ expect(button).toHaveTextContent('Search');
23
+ });
24
+
25
+ it('renders with error message', () => {
26
+ render(<InputWithButton error="Invalid email" data-testid="input-with-button" />);
27
+
28
+ const errorMessage = screen.getByText('Invalid email');
29
+ expect(errorMessage).toBeInTheDocument();
30
+ });
31
+
32
+ it('calls onButtonClick when button is clicked', () => {
33
+ const handleClick = vi.fn();
34
+ render(<InputWithButton onButtonClick={handleClick} data-testid="input-with-button" />);
35
+
36
+ const button = screen.getByRole('button');
37
+ fireEvent.click(button);
38
+
39
+ expect(handleClick).toHaveBeenCalledTimes(1);
40
+ });
41
+
42
+ it('handles input change', () => {
43
+ const handleChange = vi.fn();
44
+ render(<InputWithButton onChange={handleChange} data-testid="input-with-button" />);
45
+
46
+ const input = screen.getByTestId('input-with-button');
47
+ fireEvent.change(input, { target: { value: 'test' } });
48
+
49
+ expect(handleChange).toHaveBeenCalled();
50
+ });
51
+
52
+ it('applies disabled state to input', () => {
53
+ render(<InputWithButton disabled data-testid="input-with-button" />);
54
+
55
+ const input = screen.getByTestId('input-with-button');
56
+ expect(input).toBeDisabled();
57
+ });
58
+
59
+ it('applies disabled state to button', () => {
60
+ render(<InputWithButton buttonDisabled data-testid="input-with-button" />);
61
+
62
+ const button = screen.getByRole('button');
63
+ expect(button).toBeDisabled();
64
+ });
65
+
66
+ it('shows loading state on button', () => {
67
+ render(<InputWithButton buttonLoading data-testid="input-with-button" />);
68
+
69
+ const button = screen.getByRole('button');
70
+ expect(button).toBeDisabled();
71
+
72
+ const spinner = button.querySelector('.animate-spin');
73
+ expect(spinner).toBeInTheDocument();
74
+ });
75
+
76
+ it('applies different sizes', () => {
77
+ const { rerender } = render(<InputWithButton size="sm" data-testid="input-with-button" />);
78
+
79
+ let input = screen.getByTestId('input-with-button');
80
+ expect(input).toHaveClass('px-3', 'text-sm');
81
+
82
+ rerender(<InputWithButton size="lg" data-testid="input-with-button" />);
83
+ input = screen.getByTestId('input-with-button');
84
+ expect(input).toHaveClass('px-4', 'text-base');
85
+ });
86
+
87
+ it('applies success state', () => {
88
+ render(<InputWithButton success data-testid="input-with-button" />);
89
+
90
+ const input = screen.getByTestId('input-with-button');
91
+ expect(input).toHaveClass('border-green-500');
92
+ });
93
+
94
+ it('applies error state', () => {
95
+ render(<InputWithButton error="Error message" data-testid="input-with-button" />);
96
+
97
+ const input = screen.getByTestId('input-with-button');
98
+ expect(input).toHaveAttribute('aria-invalid', 'true');
99
+ });
100
+
101
+ it('renders with custom placeholder', () => {
102
+ render(<InputWithButton placeholder="Enter text here" data-testid="input-with-button" />);
103
+
104
+ const input = screen.getByTestId('input-with-button');
105
+ expect(input).toHaveAttribute('placeholder', 'Enter text here');
106
+ });
107
+
108
+ it('forwards ref to input element', () => {
109
+ const ref = vi.fn();
110
+ render(<InputWithButton ref={ref} data-testid="input-with-button" />);
111
+
112
+ expect(ref).toHaveBeenCalled();
113
+ });
114
+
115
+ it('renders with custom test id', () => {
116
+ render(<InputWithButton data-testid="custom-test-id" />);
117
+
118
+ const input = screen.getByTestId('custom-test-id');
119
+ expect(input).toBeInTheDocument();
120
+ });
121
+
122
+ it('does not render error when not provided', () => {
123
+ render(<InputWithButton data-testid="input-with-button" />);
124
+
125
+ const error = screen.queryByText('Error message');
126
+ expect(error).not.toBeInTheDocument();
127
+ });
128
+ });