@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,254 @@
1
+ import { ComponentProps, forwardRef, useCallback, useMemo, useRef, useState, useEffect } from 'react';
2
+
3
+ import * as Select from '@radix-ui/react-select';
4
+ import { ChevronDown } from 'lucide-react';
5
+
6
+ import {
7
+ CURRENCY_OPTIONS,
8
+ getCurrencyByCode,
9
+ getDefaultCurrency,
10
+ formatMinorUnitsToNumberString,
11
+ parseCurrencyToMinorUnits,
12
+ type CurrencyOption,
13
+ } from '@/utils/currency';
14
+
15
+ import { Flex } from '../Flex';
16
+ import { RenderCondition } from '../RenderCondition';
17
+
18
+ import { cn } from '@/utils';
19
+
20
+ const INPUT_BASE_CLASSES = [
21
+ 'h-full flex min-w-0 w-full',
22
+ 'placeholder:text-gray-500 leading-10! placeholder:leading-10!',
23
+ 'border-0 bg-transparent',
24
+ 'outline-none',
25
+ 'disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',
26
+ ].join(' ');
27
+
28
+ const CONTAINER_BASE_CLASSES = [
29
+ 'border border-gray-300 flex justify-between items-center w-full min-w-0 rounded-2xl bg-white',
30
+ 'shadow-xs transition-[color,box-shadow]',
31
+ 'focus-within:ring-2 focus-within:ring-primary focus-within:ring-offset-2',
32
+ 'disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',
33
+ ].join(' ');
34
+
35
+ const CONTAINER_SIZE_CLASSES = {
36
+ sm: 'h-10',
37
+ md: 'h-10',
38
+ lg: 'h-11',
39
+ } as const;
40
+
41
+ const SIZE_CLASSES = {
42
+ sm: 'pl-2 pr-3',
43
+ md: 'pl-2 pr-[14px]',
44
+ lg: 'pl-2 pr-4',
45
+ } as const;
46
+
47
+ const TEXT_SIZE_CLASSES = {
48
+ sm: 'text-sm',
49
+ md: 'text-base',
50
+ lg: 'text-base',
51
+ } as const;
52
+
53
+ const ERROR_CLASSES = 'border-error-500 ring-error-500/20';
54
+ const SUCCESS_CLASSES = 'border-green-500 ring-green-500/20';
55
+
56
+ export interface InputMoneyProps extends Omit<ComponentProps<'input'>, 'size' | 'type' | 'onChange' | 'value' | 'defaultValue'> {
57
+ error?: boolean;
58
+ success?: boolean;
59
+ size?: keyof typeof SIZE_CLASSES;
60
+ defaultCurrency?: string;
61
+ availableCurrencies?: string[];
62
+ onCurrencyChange?: (currency: CurrencyOption) => void;
63
+ onChange?: (minorUnits: number, currencyCode: string) => void;
64
+ minorUnits?: number;
65
+ defaultMinorUnits?: number;
66
+ 'data-testid'?: string;
67
+ }
68
+
69
+ const InputMoneyComponent = forwardRef<HTMLInputElement, InputMoneyProps>(
70
+ ({
71
+ className,
72
+ error = false,
73
+ success = false,
74
+ size = 'md',
75
+ disabled,
76
+ defaultCurrency,
77
+ availableCurrencies,
78
+ onCurrencyChange,
79
+ onChange,
80
+ minorUnits,
81
+ defaultMinorUnits = 0,
82
+ 'data-testid': testId,
83
+ ...props
84
+ }, ref) => {
85
+ const [ selectedCurrency, setSelectedCurrency ] = useState<CurrencyOption>(() => {
86
+ if (defaultCurrency) {
87
+ const currency = getCurrencyByCode(defaultCurrency);
88
+
89
+ if (currency) return currency;
90
+ }
91
+
92
+ return getDefaultCurrency();
93
+ });
94
+
95
+ const isControlled = typeof minorUnits === 'number';
96
+ const [ internalMinorUnits, setInternalMinorUnits ] = useState<number>(defaultMinorUnits);
97
+
98
+ const inputRef = useRef<HTMLInputElement>(null);
99
+
100
+ useEffect(() => {
101
+ if (isControlled && typeof minorUnits === 'number') {
102
+ setInternalMinorUnits(minorUnits);
103
+ }
104
+ }, [ isControlled, minorUnits ]);
105
+
106
+ const isDisabled = disabled;
107
+
108
+ const filteredCurrencies = useMemo(() => {
109
+ if (!availableCurrencies) return CURRENCY_OPTIONS as CurrencyOption[];
110
+
111
+ return (CURRENCY_OPTIONS as CurrencyOption[]).filter(currency =>
112
+ availableCurrencies.includes(currency.code)
113
+ );
114
+ }, [ availableCurrencies ]);
115
+
116
+ const shouldShowCurrencySelect = !!filteredCurrencies?.length && filteredCurrencies.length > 1;
117
+ const currentMinorUnits = isControlled ? (minorUnits || 0) : internalMinorUnits;
118
+
119
+ const displayValue = useMemo(() => {
120
+ return formatMinorUnitsToNumberString(currentMinorUnits, selectedCurrency.locale);
121
+ }, [ currentMinorUnits, selectedCurrency.locale ]);
122
+
123
+ const handleCurrencyChange = useCallback((currencyCode: string) => {
124
+ const currency = getCurrencyByCode(currencyCode);
125
+
126
+ if (currency) {
127
+ setSelectedCurrency(currency);
128
+ onCurrencyChange?.(currency);
129
+ onChange?.(currentMinorUnits, currency.code);
130
+ }
131
+ }, [ onCurrencyChange, onChange, currentMinorUnits ]);
132
+
133
+ const handleMoneyChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
134
+ const inputValue = e.target.value || '';
135
+ const parsedMinorUnits = parseCurrencyToMinorUnits(inputValue);
136
+
137
+ if (!isControlled) {
138
+ setInternalMinorUnits(parsedMinorUnits);
139
+ }
140
+
141
+ onChange?.(parsedMinorUnits, selectedCurrency.code);
142
+
143
+ if (inputRef.current) {
144
+ inputRef.current.value = formatMinorUnitsToNumberString(parsedMinorUnits, selectedCurrency.locale);
145
+ }
146
+ }, [ isControlled, onChange, selectedCurrency.code, selectedCurrency.locale ]);
147
+
148
+ const containerClasses = cn(
149
+ CONTAINER_BASE_CLASSES,
150
+ CONTAINER_SIZE_CLASSES[size],
151
+ {
152
+ [ERROR_CLASSES]: error,
153
+ [SUCCESS_CLASSES]: success && !error,
154
+ },
155
+ className
156
+ );
157
+
158
+ const inputClasses = cn(
159
+ INPUT_BASE_CLASSES,
160
+ SIZE_CLASSES[size],
161
+ TEXT_SIZE_CLASSES[size]
162
+ );
163
+
164
+ const getPlaceholder = () => formatMinorUnitsToNumberString(0, selectedCurrency.locale);
165
+
166
+ return (
167
+ <div className={containerClasses}>
168
+ <span className={cn(TEXT_SIZE_CLASSES[size], 'font-medium text-gray-700 pl-3 pr-2')}>{selectedCurrency.symbol}</span>
169
+
170
+ <input
171
+ ref={(node) => {
172
+ if (typeof ref === 'function') ref(node);
173
+ else if (ref) ref.current = node;
174
+
175
+ if (node) inputRef.current = node;
176
+ }}
177
+ type="text"
178
+ disabled={isDisabled}
179
+ data-slot="input"
180
+ data-testid={testId}
181
+ className={inputClasses}
182
+ aria-invalid={error}
183
+ value={displayValue}
184
+ onChange={handleMoneyChange}
185
+ placeholder={getPlaceholder()}
186
+ maxLength={props.maxLength ?? 32}
187
+ {...props}
188
+ />
189
+
190
+ <RenderCondition condition={shouldShowCurrencySelect}>
191
+ <Flex className="items-center pl-2 pr-2">
192
+ <Select.Root
193
+ value={selectedCurrency.code}
194
+ onValueChange={handleCurrencyChange}
195
+ disabled={isDisabled}
196
+ >
197
+ <Select.Trigger
198
+ className={cn(
199
+ 'flex items-center gap-1 bg-transparent outline-none border-0 cursor-pointer',
200
+ 'font-medium text-gray-700',
201
+ 'focus:outline-none',
202
+ {
203
+ 'opacity-50 cursor-not-allowed': isDisabled,
204
+ },
205
+ TEXT_SIZE_CLASSES[size]
206
+ )}
207
+ data-testid="currency-select"
208
+ >
209
+ <Select.Value>
210
+ <span>{selectedCurrency.code}</span>
211
+ </Select.Value>
212
+ <Select.Icon>
213
+ <ChevronDown className="size-4 text-gray-400" />
214
+ </Select.Icon>
215
+ </Select.Trigger>
216
+
217
+ <Select.Portal>
218
+ <Select.Content
219
+ position="popper"
220
+ sideOffset={4}
221
+ className={cn(
222
+ 'z-50 min-w-24 rounded-md border border-gray-200 bg-white shadow-lg',
223
+ 'max-h-60 overflow-y-auto py-2'
224
+ )}
225
+ >
226
+ <Select.Viewport className="p-1">
227
+ {filteredCurrencies.map((currency, index) => (
228
+ <Select.Item
229
+ key={`${currency.code}-${index}`}
230
+ value={currency.code}
231
+ className={cn(
232
+ 'relative flex cursor-pointer select-none items-center rounded-sm px-3 py-2 text-sm',
233
+ 'text-gray-700 outline-none font-medium',
234
+ 'hover:bg-gray-50 hover:text-primary focus:bg-gray-50 focus:text-primary',
235
+ 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50'
236
+ )}
237
+ >
238
+ <Select.ItemText>{currency.code}</Select.ItemText>
239
+ </Select.Item>
240
+ ))}
241
+ </Select.Viewport>
242
+ </Select.Content>
243
+ </Select.Portal>
244
+ </Select.Root>
245
+ </Flex>
246
+ </RenderCondition>
247
+ </div>
248
+ );
249
+ }
250
+ );
251
+
252
+ InputMoneyComponent.displayName = 'InputMoney';
253
+
254
+ export const InputMoney = InputMoneyComponent;
@@ -0,0 +1,2 @@
1
+ export type { InputPhoneProps, PhoneValue } from './input-phone';
2
+ export { InputPhone } from './input-phone';
@@ -0,0 +1,447 @@
1
+ import { useState } from 'react';
2
+
3
+ import { InputPhone } from './input-phone';
4
+
5
+ import type { Meta, StoryObj } from '@storybook/react';
6
+
7
+ import { CountryCode } from '@/utils';
8
+
9
+ const meta: Meta<typeof InputPhone> = {
10
+ title: 'Components/Data Entry/InputPhone',
11
+ component: InputPhone,
12
+ tags: [ 'autodocs' ],
13
+ parameters: {
14
+ layout: 'centered',
15
+ docs: {
16
+ description: {
17
+ component: 'A phone input component with international country code selector. Features a unified container with a discrete HTML select for country selection, country code display, and a masked input for phone numbers. The placeholder automatically shows the full format including country code.',
18
+ },
19
+ },
20
+ },
21
+ argTypes: {
22
+ size: {
23
+ control: { type: 'select' },
24
+ options: [ 'sm', 'md', 'lg' ],
25
+ description: 'Size of the input field',
26
+ },
27
+ error: {
28
+ control: { type: 'boolean' },
29
+ description: 'Error state styling',
30
+ },
31
+ success: {
32
+ control: { type: 'boolean' },
33
+ description: 'Success state styling',
34
+ },
35
+ disabled: {
36
+ control: { type: 'boolean' },
37
+ description: 'Disabled state',
38
+ },
39
+ defaultCountry: {
40
+ control: { type: 'select' },
41
+ options: [ '+55', '+1', '+44', '+33', '+49' ],
42
+ description: 'Default country code',
43
+ },
44
+ availableCountries: {
45
+ control: { type: 'object' },
46
+ description: 'Array of available country codes',
47
+ },
48
+ placeholder: {
49
+ control: { type: 'text' },
50
+ description: 'Placeholder text',
51
+ },
52
+ },
53
+ };
54
+
55
+ export default meta;
56
+ type Story = StoryObj<typeof meta>;
57
+
58
+ const InteractiveExample = () => {
59
+ const [ phone, setPhone ] = useState('');
60
+ const [ country, setCountry ] = useState('+55');
61
+ const [ hasError, setHasError ] = useState(false);
62
+
63
+ const handlePhoneChange = (value: string, countryCode: string) => {
64
+ setPhone(value);
65
+ setCountry(countryCode);
66
+ setHasError(false);
67
+ };
68
+
69
+ const handleCountryChange = (selectedCountry: CountryCode) => {
70
+ setCountry(selectedCountry.code);
71
+ setPhone('');
72
+ setHasError(false);
73
+ };
74
+
75
+ const validatePhone = () => {
76
+ const isValid = phone.length > 0;
77
+ setHasError(!isValid);
78
+ return isValid;
79
+ };
80
+
81
+ return (
82
+ <div className="w-80 space-y-4 p-6 border rounded-lg">
83
+ <h3 className="text-lg font-semibold mb-4">Phone Number Form</h3>
84
+
85
+ <div>
86
+ <label className="block text-sm font-medium text-gray-700 mb-1">
87
+ Phone Number *
88
+ </label>
89
+ <InputPhone
90
+ value={phone}
91
+ onChange={handlePhoneChange}
92
+ onCountryChange={handleCountryChange}
93
+ error={hasError}
94
+ />
95
+ {hasError && (
96
+ <p className="text-sm text-red-600 mt-1">Please enter a valid phone number</p>
97
+ )}
98
+ </div>
99
+
100
+ <div className="text-sm text-gray-600">
101
+ <p>Selected country: {country}</p>
102
+ <p>Phone number: {phone || 'Not entered'}</p>
103
+ </div>
104
+
105
+ <button
106
+ type="button"
107
+ onClick={validatePhone}
108
+ className="w-full bg-blue-500 text-white py-2 px-4 rounded-md hover:bg-blue-600 transition-colors"
109
+ >
110
+ Validate Phone
111
+ </button>
112
+ </div>
113
+ );
114
+ };
115
+
116
+ const FormWithValidation = () => {
117
+ const [ formData, setFormData ] = useState({
118
+ name: '',
119
+ phone: '',
120
+ countryCode: '+55',
121
+ });
122
+ const [ errors, setErrors ] = useState<Record<string, string>>({});
123
+
124
+ const handlePhoneChange = (phone: string, countryCode: string) => {
125
+ setFormData(prev => ({
126
+ ...prev,
127
+ phone,
128
+ countryCode,
129
+ }));
130
+
131
+ if (errors.phone) {
132
+ setErrors(prev => ({ ...prev, phone: '' }));
133
+ }
134
+ };
135
+
136
+ const handleSubmit = (e: React.FormEvent) => {
137
+ e.preventDefault();
138
+ const newErrors: Record<string, string> = {};
139
+
140
+ if (!formData.name.trim()) {
141
+ newErrors.name = 'Name is required';
142
+ }
143
+
144
+ if (!formData.phone.trim()) {
145
+ newErrors.phone = 'Phone number is required';
146
+ } else if (formData.phone.length < 10) {
147
+ newErrors.phone = 'Please enter a complete phone number';
148
+ }
149
+
150
+ setErrors(newErrors);
151
+
152
+ if (Object.keys(newErrors).length === 0) {
153
+ alert(`Form submitted!\nName: ${formData.name}\nPhone: ${formData.countryCode} ${formData.phone}`);
154
+ }
155
+ };
156
+
157
+ return (
158
+ <form onSubmit={handleSubmit} className="w-80 space-y-4 p-6 border rounded-lg">
159
+ <h3 className="text-lg font-semibold mb-4">Contact Form</h3>
160
+
161
+ <div>
162
+ <label className="block text-sm font-medium text-gray-700 mb-1">
163
+ Name *
164
+ </label>
165
+ <input
166
+ type="text"
167
+ value={formData.name}
168
+ onChange={(e) => setFormData(prev => ({ ...prev, name: e.target.value }))}
169
+ className="w-full border border-gray-300 rounded-2xl px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
170
+ placeholder="Enter your name"
171
+ />
172
+ {errors.name && (
173
+ <p className="text-sm text-red-600 mt-1">{errors.name}</p>
174
+ )}
175
+ </div>
176
+
177
+ <div>
178
+ <label className="block text-sm font-medium text-gray-700 mb-1">
179
+ Phone Number *
180
+ </label>
181
+ <InputPhone
182
+ value={formData.phone}
183
+ onChange={handlePhoneChange}
184
+ error={!!errors.phone}
185
+ />
186
+ {errors.phone && (
187
+ <p className="text-sm text-red-600 mt-1">{errors.phone}</p>
188
+ )}
189
+ </div>
190
+
191
+ <button
192
+ type="submit"
193
+ className="w-full bg-blue-500 text-white py-2 px-4 rounded-md hover:bg-blue-600 transition-colors"
194
+ >
195
+ Submit Form
196
+ </button>
197
+ </form>
198
+ );
199
+ };
200
+
201
+ export const AllSizesBasic: Story = {
202
+ name: 'All Sizes Showcase',
203
+ render: () => (
204
+ <div className="space-y-6">
205
+ <div>
206
+ <h4 className="text-sm font-medium text-gray-700 mb-2">Small</h4>
207
+ <div className="space-y-2">
208
+ <InputPhone size="sm" />
209
+ <InputPhone size="sm" defaultCountry="+1" />
210
+ <InputPhone size="sm" defaultCountry="+44" />
211
+ </div>
212
+ </div>
213
+
214
+ <div>
215
+ <h4 className="text-sm font-medium text-gray-700 mb-2">Medium</h4>
216
+ <div className="space-y-2">
217
+ <InputPhone size="md" />
218
+ <InputPhone size="md" defaultCountry="+1" />
219
+ <InputPhone size="md" defaultCountry="+44" />
220
+ </div>
221
+ </div>
222
+
223
+ <div>
224
+ <h4 className="text-sm font-medium text-gray-700 mb-2">Large</h4>
225
+ <div className="space-y-2">
226
+ <InputPhone size="lg" />
227
+ <InputPhone size="lg" defaultCountry="+1" />
228
+ <InputPhone size="lg" defaultCountry="+44" />
229
+ </div>
230
+ </div>
231
+ </div>
232
+ ),
233
+ parameters: {
234
+ docs: {
235
+ description: {
236
+ story: 'Comparison of all available sizes with different country codes.',
237
+ },
238
+ },
239
+ },
240
+ };
241
+
242
+ export const AllStatesBasic: Story = {
243
+ name: 'All States Showcase',
244
+ render: () => (
245
+ <div className="space-y-4">
246
+ <div>
247
+ <h4 className="text-sm font-medium text-gray-700 mb-2">Normal</h4>
248
+ <InputPhone placeholder="Normal state" defaultValue="(11) 9 8765-4321" />
249
+ </div>
250
+
251
+ <div>
252
+ <h4 className="text-sm font-medium text-gray-700 mb-2">Error</h4>
253
+ <InputPhone error placeholder="Error state" defaultValue="(11) 9 8765-4321" />
254
+ </div>
255
+
256
+ <div>
257
+ <h4 className="text-sm font-medium text-gray-700 mb-2">Success</h4>
258
+ <InputPhone success placeholder="Success state" defaultValue="(11) 9 8765-4321" />
259
+ </div>
260
+
261
+ <div>
262
+ <h4 className="text-sm font-medium text-gray-700 mb-2">Disabled</h4>
263
+ <InputPhone disabled placeholder="Disabled state" defaultValue="(11) 9 8765-4321" />
264
+ </div>
265
+ </div>
266
+ ),
267
+ parameters: {
268
+ docs: {
269
+ description: {
270
+ story: 'Showcase of all available states and their visual feedback.',
271
+ },
272
+ },
273
+ },
274
+ };
275
+
276
+ export const CountryCodesShowcase: Story = {
277
+ name: 'Country Codes Showcase',
278
+ render: () => (
279
+ <div className="space-y-4 w-80">
280
+ <div>
281
+ <label className="block text-sm font-medium text-gray-700 mb-1">Brazil</label>
282
+ <InputPhone defaultCountry="+55" />
283
+ </div>
284
+ <div>
285
+ <label className="block text-sm font-medium text-gray-700 mb-1">United States</label>
286
+ <InputPhone defaultCountry="+1" />
287
+ </div>
288
+ <div>
289
+ <label className="block text-sm font-medium text-gray-700 mb-1">United Kingdom</label>
290
+ <InputPhone defaultCountry="+44" />
291
+ </div>
292
+ <div>
293
+ <label className="block text-sm font-medium text-gray-700 mb-1">France</label>
294
+ <InputPhone defaultCountry="+33" />
295
+ </div>
296
+ <div>
297
+ <label className="block text-sm font-medium text-gray-700 mb-1">Germany</label>
298
+ <InputPhone defaultCountry="+49" />
299
+ </div>
300
+ </div>
301
+ ),
302
+ parameters: {
303
+ docs: {
304
+ description: {
305
+ story: 'Different country codes with their respective phone formats and masks.',
306
+ },
307
+ },
308
+ },
309
+ };
310
+
311
+ export const Default: Story = {
312
+ args: {
313
+ placeholder: 'Digite seu telefone',
314
+ },
315
+ };
316
+
317
+ export const Disabled: Story = {
318
+ args: {
319
+ disabled: true,
320
+ placeholder: 'Digite seu telefone',
321
+ defaultValue: '(11) 9 8765-4321',
322
+ },
323
+ };
324
+
325
+ export const FormWithValidationStory: Story = {
326
+ name: 'Form with Validation',
327
+ render: () => <FormWithValidation />,
328
+ parameters: {
329
+ docs: {
330
+ description: {
331
+ story: 'A complete form example with validation using the InputPhone component.',
332
+ },
333
+ },
334
+ },
335
+ };
336
+
337
+ export const Interactive: Story = {
338
+ name: 'Interactive Form Example',
339
+ render: () => <InteractiveExample />,
340
+ parameters: {
341
+ docs: {
342
+ description: {
343
+ story: 'A complete form example showing different input types, states, and validation.',
344
+ },
345
+ },
346
+ },
347
+ };
348
+
349
+ export const Large: Story = {
350
+ args: {
351
+ size: 'lg',
352
+ placeholder: 'Digite seu telefone',
353
+ },
354
+ };
355
+
356
+ export const LimitedCountries: Story = {
357
+ name: 'Limited Countries',
358
+ args: {
359
+ availableCountries: [ '+55', '+1', '+44', '+33' ],
360
+ placeholder: 'Digite seu telefone',
361
+ },
362
+ };
363
+
364
+ export const LimitedCountriesShowcase: Story = {
365
+ name: 'Limited Countries Showcase',
366
+ render: () => (
367
+ <div className="space-y-4 w-80">
368
+ <div>
369
+ <label className="block text-sm font-medium text-gray-700 mb-1">Americas Only</label>
370
+ <InputPhone
371
+ availableCountries={[ '+55', '+1', '+52', '+54', '+56' ]}
372
+
373
+ />
374
+ </div>
375
+ <div>
376
+ <label className="block text-sm font-medium text-gray-700 mb-1">Europe Only</label>
377
+ <InputPhone
378
+ availableCountries={[ '+44', '+33', '+49', '+39', '+34' ]}
379
+
380
+ />
381
+ </div>
382
+ <div>
383
+ <label className="block text-sm font-medium text-gray-700 mb-1">Asia Only</label>
384
+ <InputPhone
385
+ availableCountries={[ '+81', '+82', '+86', '+91' ]}
386
+
387
+ />
388
+ </div>
389
+ </div>
390
+ ),
391
+ parameters: {
392
+ docs: {
393
+ description: {
394
+ story: 'Examples of limiting available countries by region.',
395
+ },
396
+ },
397
+ },
398
+ };
399
+
400
+ export const Loading: Story = {
401
+ name: 'Loading State',
402
+ args: {
403
+ loading: true,
404
+ placeholder: 'Processing...',
405
+ defaultValue: '(11) 9 8765-4321',
406
+ },
407
+ };
408
+
409
+ export const Medium: Story = {
410
+ args: {
411
+ size: 'md',
412
+ placeholder: 'Digite seu telefone',
413
+ },
414
+ };
415
+
416
+ export const Small: Story = {
417
+ args: {
418
+ size: 'sm',
419
+ placeholder: 'Digite seu telefone',
420
+ },
421
+ };
422
+
423
+ export const WithDefaultCountry: Story = {
424
+ name: 'With Default Country (US)',
425
+ args: {
426
+ defaultCountry: '+1',
427
+ placeholder: 'Enter your phone number',
428
+ },
429
+ };
430
+
431
+ export const WithError: Story = {
432
+ name: 'Error State',
433
+ args: {
434
+ error: true,
435
+ placeholder: 'Digite seu telefone',
436
+ defaultValue: '(11) 9 8765-4321',
437
+ },
438
+ };
439
+
440
+ export const WithSuccess: Story = {
441
+ name: 'Success State',
442
+ args: {
443
+ success: true,
444
+ placeholder: 'Digite seu telefone',
445
+ defaultValue: '(11) 9 8765-4321',
446
+ },
447
+ };