@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,112 @@
1
+ import { Meta, StoryObj } from '@storybook/react';
2
+
3
+ import { Dropdown } from './dropdown';
4
+
5
+ import { Tag01, User01, Building06, Briefcase01 } from '@/components';
6
+
7
+ type OptionType = {
8
+ label: string;
9
+ value: string;
10
+ icon?: React.ReactNode;
11
+ };
12
+
13
+ const options: OptionType[] = [
14
+ { value: 'react', label: 'React' },
15
+ { value: 'next', label: 'Next.js' },
16
+ { value: 'typescript', label: 'TypeScript' },
17
+ ];
18
+
19
+ const optionsWithDynamicIcons: OptionType[] = [
20
+ { value: 'user', label: 'User Profile', icon: <User01 className="size-4" /> },
21
+ { value: 'company', label: 'Company', icon: <Building06 className="size-4" /> },
22
+ { value: 'business', label: 'Business', icon: <Briefcase01 className="size-4" /> },
23
+ { value: 'react', label: 'React' },
24
+ { value: 'next', label: 'Next.js' },
25
+ ];
26
+
27
+ const meta: Meta<typeof Dropdown<OptionType>> = {
28
+ title: 'Components/Data entry/Dropdown',
29
+ component: Dropdown,
30
+ tags: [ 'autodocs' ],
31
+ args: {
32
+ options,
33
+ placeholder: 'Select an option...',
34
+ isClearable: true,
35
+ size: 'md',
36
+ },
37
+ };
38
+
39
+ export default meta;
40
+
41
+ type Story = StoryObj<typeof Dropdown<OptionType>>;
42
+
43
+ export const Creatable = {
44
+ args: {
45
+ creatable: true,
46
+ placeholder: 'Select or create an option...',
47
+ },
48
+ };
49
+
50
+ export const CreatableMultiSelect = {
51
+ args: {
52
+ creatable: true,
53
+ isMulti: true,
54
+ placeholder: 'Select or create multiple options...',
55
+ },
56
+ };
57
+
58
+ export const CreatableWithSearchIcon = {
59
+ args: {
60
+ creatable: true,
61
+ showSearchIcon: true,
62
+ placeholder: 'Search, select or create an option...',
63
+ },
64
+ };
65
+
66
+ export const Default: Story = {};
67
+
68
+ export const Disabled = {
69
+ args: {
70
+ isDisabled: true,
71
+ placeholder: 'Disabled',
72
+ },
73
+ };
74
+
75
+ export const MultiSelect = {
76
+ args: {
77
+ isMulti: true,
78
+ size: 'sm',
79
+ showSearchIcon: true,
80
+ multiValueIcon: <Tag01 className="size-5" />,
81
+ },
82
+ };
83
+
84
+ export const MultiSelectWithDynamicIcons = {
85
+ args: {
86
+ options: optionsWithDynamicIcons,
87
+ isMulti: true,
88
+ size: 'sm',
89
+ showSearchIcon: true,
90
+ placeholder: 'Select multiple options with dynamic icons...',
91
+ },
92
+ parameters: {
93
+ docs: {
94
+ description: {
95
+ story: 'This example demonstrates how to use dynamic multiValueIcon per option. Each option can have its own icon via the `multiValueIcon` property, and options without this property will use the fallback icon provided to the component.',
96
+ },
97
+ },
98
+ },
99
+ };
100
+
101
+ export const WithIcon = {
102
+ args: {
103
+ icon: <Tag01 className="size-5" />,
104
+ },
105
+ };
106
+
107
+ export const WithSearchIcon = {
108
+ args: {
109
+ showSearchIcon: true,
110
+ placeholder: 'Search and select an option...',
111
+ },
112
+ };
@@ -0,0 +1,128 @@
1
+ import { render, screen, fireEvent } from '@testing-library/react';
2
+ import { describe, it, expect, vi } from 'vitest';
3
+
4
+ import { Dropdown } from './dropdown';
5
+
6
+ type OptionType = {
7
+ label: string;
8
+ value: string;
9
+ };
10
+
11
+ const options: OptionType[] = [
12
+ { label: 'Option One', value: 'one' },
13
+ { label: 'Option Two', value: 'two' },
14
+ { label: 'Option Three', value: 'three' },
15
+ ];
16
+
17
+ const renderDropdown = (props = {}) =>
18
+ render(
19
+ <Dropdown<OptionType> options={options} placeholder="Select an option" {...props} />
20
+ );
21
+
22
+ describe('<Dropdown />', () => {
23
+ it('renders without crashing', () => {
24
+ renderDropdown();
25
+ expect(screen.getByText('Select an option')).toBeInTheDocument();
26
+ });
27
+
28
+ it('displays options when clicked', async () => {
29
+ renderDropdown();
30
+ const placeholder = screen.getByText('Select an option');
31
+ fireEvent.mouseDown(placeholder);
32
+ expect(await screen.findByText('Option One')).toBeInTheDocument();
33
+ expect(screen.getByText('Option Two')).toBeInTheDocument();
34
+ expect(screen.getByText('Option Three')).toBeInTheDocument();
35
+ });
36
+
37
+ it('selects a single option correctly', async () => {
38
+ renderDropdown();
39
+ fireEvent.mouseDown(screen.getByText('Select an option'));
40
+ fireEvent.click(screen.getByText('Option Two'));
41
+ expect(screen.getByText('Option Two')).toBeInTheDocument();
42
+ });
43
+
44
+ it('supports multi-select mode', async () => {
45
+ renderDropdown({ isMulti: true });
46
+ const combobox = screen.getByRole('combobox');
47
+ fireEvent.mouseDown(combobox);
48
+ fireEvent.click(screen.getByText('Option One'));
49
+ fireEvent.mouseDown(combobox);
50
+ fireEvent.click(screen.getByText('Option Two'));
51
+ expect(screen.getByText('Option One')).toBeInTheDocument();
52
+ expect(screen.getByText('Option Two')).toBeInTheDocument();
53
+ });
54
+
55
+ it('shows custom no options message if no match', () => {
56
+ renderDropdown({ options: [], noOptionsMessage: () => 'No options found' });
57
+ fireEvent.mouseDown(screen.getByText('Select an option'));
58
+ expect(screen.getByText('No options found')).toBeInTheDocument();
59
+ });
60
+
61
+ it('applies custom classNames correctly', () => {
62
+ const customClass = 'custom-class';
63
+ renderDropdown({
64
+ classNames: {
65
+ valueContainer: () => customClass,
66
+ },
67
+ });
68
+ const valueContainer = screen.getByRole('combobox').parentElement?.parentElement;
69
+ expect(valueContainer?.className).toContain(customClass);
70
+ });
71
+
72
+ it('should match snapshot', () => {
73
+ const { container } = renderDropdown();
74
+ expect(container).toMatchSnapshot();
75
+ });
76
+
77
+ it('allows creating new options when creatable is true', async () => {
78
+ const onChange = vi.fn();
79
+ renderDropdown({ creatable: true, onChange });
80
+
81
+ const input = screen.getByRole('combobox');
82
+ fireEvent.change(input, { target: { value: 'New Option' } });
83
+
84
+ // Wait for the "Create" option to appear
85
+ const createOption = await screen.findByText('Criar "New Option"');
86
+ fireEvent.click(createOption);
87
+
88
+ expect(onChange).toHaveBeenCalledWith(
89
+ expect.objectContaining({
90
+ label: 'New Option',
91
+ value: 'New Option',
92
+ }),
93
+ expect.anything()
94
+ );
95
+ });
96
+
97
+ it('does not show create option when creatable is false', async () => {
98
+ renderDropdown({ creatable: false });
99
+
100
+ const input = screen.getByRole('combobox');
101
+ fireEvent.change(input, { target: { value: 'New Option' } });
102
+
103
+ // Wait a bit to ensure no create option appears
104
+ await new Promise(resolve => setTimeout(resolve, 100));
105
+ expect(screen.queryByText('Criar "New Option"')).not.toBeInTheDocument();
106
+ });
107
+
108
+ it('supports creating new options in multi-select mode', async () => {
109
+ const onChange = vi.fn();
110
+ renderDropdown({ creatable: true, isMulti: true, onChange });
111
+
112
+ const input = screen.getByRole('combobox');
113
+ fireEvent.change(input, { target: { value: 'New Option' } });
114
+
115
+ const createOption = await screen.findByText('Criar "New Option"');
116
+ fireEvent.click(createOption);
117
+
118
+ expect(onChange).toHaveBeenCalledWith(
119
+ expect.arrayContaining([
120
+ expect.objectContaining({
121
+ label: 'New Option',
122
+ value: 'New Option',
123
+ }),
124
+ ]),
125
+ expect.anything()
126
+ );
127
+ });
128
+ });
@@ -0,0 +1,322 @@
1
+ import React from 'react';
2
+
3
+ import { Loader2 } from 'lucide-react';
4
+ import Select, { ClassNamesConfig, ClearIndicatorProps, components, ControlProps, DropdownIndicatorProps, GroupBase, MultiValueGenericProps, MultiValueRemoveProps, OptionProps, Props as ReactSelectProps } from 'react-select';
5
+ import CreatableSelect, { CreatableProps } from 'react-select/creatable';
6
+ import { AsyncPaginate, ComponentProps, UseAsyncPaginateParams } from 'react-select-async-paginate';
7
+
8
+ import { ChevronDown, PlusCircle, SearchLg, XClose } from '@/components/icons';
9
+
10
+ import { RenderCondition } from '@/main';
11
+ import { cn, renderHighlightedText } from '@/utils';
12
+
13
+ type OptionsType = { label: string; icon?: React.ReactNode; value: string };
14
+
15
+ type DropdownProps<
16
+ OptionType extends OptionsType,
17
+ IsMulti extends boolean = false,
18
+ Group extends GroupBase<OptionType> = GroupBase<OptionType>,
19
+ > = ReactSelectProps<OptionType, IsMulti, Group> & {
20
+ creatable?: boolean;
21
+ isDisabled?: boolean;
22
+ showSearchIcon?: boolean;
23
+ size?: 'sm' | 'md' | 'lg';
24
+ icon?: React.ReactNode;
25
+ rounded?: 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full';
26
+ createLabel?: string;
27
+ };
28
+
29
+ type AsyncPaginateCreatableProps<
30
+ OptionType extends OptionsType,
31
+ IsMulti extends boolean = false,
32
+ Additional = { page: number },
33
+ Group extends GroupBase<OptionType> = GroupBase<OptionType>
34
+ > =
35
+ & CreatableProps<OptionType, IsMulti, Group>
36
+ & UseAsyncPaginateParams<OptionType, Group, Additional>
37
+ & ComponentProps<OptionType, Group, IsMulti>
38
+ & Pick<DropdownProps<OptionType, IsMulti, Group>, 'isDisabled' | 'showSearchIcon' | 'size' | 'icon' | 'rounded'>;
39
+
40
+ const CustomMultiValueLabel = ({ data }: { data: OptionsType }) => {
41
+ const label = data.label.length > 20 ? `${data.label.slice(0, 20)}…` : data.label;
42
+ return <span title={data.label}>{label}</span>;
43
+ };
44
+
45
+ const CustomMultiValueContainer = <
46
+ Option extends OptionsType,
47
+ IsMulti extends boolean = false,
48
+ Group extends GroupBase<Option> = GroupBase<Option>,
49
+ >({
50
+ children,
51
+ ...props
52
+ }: MultiValueGenericProps<Option, IsMulti, Group>) => {
53
+ const optionIcon = (props.data as Option)?.icon;
54
+
55
+ return (
56
+ <components.MultiValueContainer {...props}>
57
+ <RenderCondition condition={!!optionIcon}>
58
+ <div className="flex items-center justify-center mr-1 size-4">
59
+ {optionIcon}
60
+ </div>
61
+ </RenderCondition>
62
+ {children}
63
+ </components.MultiValueContainer>
64
+ );
65
+ };
66
+
67
+ const CustomMultiValueRemove = <
68
+ Option extends OptionsType,
69
+ IsMulti extends boolean = false,
70
+ Group extends GroupBase<Option> = GroupBase<Option>,
71
+ >(props: MultiValueRemoveProps<Option, IsMulti, Group>) => {
72
+ return (
73
+ <components.MultiValueRemove {...props}>
74
+ <XClose className="size-4 ml-1 text-gray-400 hover:text-gray-600" />
75
+ </components.MultiValueRemove>
76
+ );
77
+ };
78
+
79
+ const CustomControl = <
80
+ Option,
81
+ IsMulti extends boolean = false,
82
+ Group extends GroupBase<Option> = GroupBase<Option>,
83
+ >({
84
+ children,
85
+ showSearchIcon = false,
86
+ icon,
87
+ ...props
88
+ }: ControlProps<Option, IsMulti, Group> & { showSearchIcon?: boolean, icon?: React.ReactNode }) => {
89
+ return (
90
+ <components.Control {...props}>
91
+ <RenderCondition condition={showSearchIcon || !!icon}>
92
+ <div className="flex items-center justify-center text-gray-400 mr-2">
93
+ <RenderCondition condition={showSearchIcon}>
94
+ <SearchLg className="size-5" />
95
+ </RenderCondition>
96
+ <RenderCondition condition={!!icon}>
97
+ {icon}
98
+ </RenderCondition>
99
+ </div>
100
+ </RenderCondition>
101
+ {children}
102
+ </components.Control>
103
+ );
104
+ };
105
+
106
+ const CustomDropdownIndicator = <
107
+ Option extends OptionsType,
108
+ IsMulti extends boolean = false,
109
+ Group extends GroupBase<Option> = GroupBase<Option>,
110
+ >(props: DropdownIndicatorProps<Option, IsMulti, Group>) => {
111
+ return (
112
+ <components.DropdownIndicator {...props}>
113
+ <ChevronDown className="size-4 text-gray-400" />
114
+ </components.DropdownIndicator>
115
+ );
116
+ };
117
+
118
+ const CustomClearIndicator = <
119
+ Option extends OptionsType,
120
+ IsMulti extends boolean = false,
121
+ Group extends GroupBase<Option> = GroupBase<Option>,
122
+ >(props: ClearIndicatorProps<Option, IsMulti, Group>) => {
123
+ return (
124
+ <components.ClearIndicator {...props}>
125
+ <XClose className="size-4 text-gray-400 hover:text-gray-600" />
126
+ </components.ClearIndicator>
127
+ );
128
+ };
129
+
130
+ const CustomOption = <
131
+ Option extends OptionsType,
132
+ IsMulti extends boolean = false,
133
+ Group extends GroupBase<Option> = GroupBase<Option>,
134
+ >(props: OptionProps<Option, IsMulti, Group>) => {
135
+ const isCreateOption = Boolean((props.data as unknown as { __isNew__?: boolean })?.__isNew__);
136
+ return (
137
+ <components.Option {...props}>
138
+ <div className="flex items-center gap-2 cursor-pointer">
139
+ <RenderCondition condition={!isCreateOption && !!props.data.icon}>
140
+ <div className="flex items-center justify-center size-4">
141
+ {props.data.icon}
142
+ </div>
143
+ </RenderCondition>
144
+ {isCreateOption ? (
145
+ <span>{props.children}</span>
146
+ ) : (
147
+ <span>
148
+ {renderHighlightedText(
149
+ String((props.data as OptionsType).label ?? ''),
150
+ (props.selectProps as unknown as { inputValue?: string })?.inputValue ?? ''
151
+ )}
152
+ </span>
153
+ )}
154
+ </div>
155
+ </components.Option>
156
+ );
157
+ };
158
+
159
+ const CustomLoadingIndicator = () => {
160
+ return <Loader2 className="size-5 mr-2 text-gray-400 animate-spin" />;
161
+ };
162
+
163
+ const customClassNames = <
164
+ OptionType extends OptionsType,
165
+ IsMulti extends boolean = false,
166
+ Group extends GroupBase<OptionType> = GroupBase<OptionType>,
167
+ >(size: 'sm' | 'md' | 'lg', rounded: 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full') => {
168
+ const defaultClassNames: ClassNamesConfig<OptionType, IsMulti, Group> = {
169
+ control: ({ isDisabled }) =>
170
+ cn(
171
+ 'bg-white placeholder:text-gray-500 selection:bg-primary cursor-pointer',
172
+ 'border border-gray-300 flex min-h-[40px]! items-center w-full min-w-0 text-base shadow-xs transition-[color,box-shadow] outline-none',
173
+ 'focus-within-primary',
174
+ isDisabled && 'opacity-50 pointer-events-none cursor-not-allowed',
175
+ {
176
+ 'px-3 py-1.5': size === 'sm',
177
+ 'px-[14px] py-1.5': size === 'md',
178
+ 'px-4 py-1.5': size === 'lg',
179
+ },
180
+ {
181
+ 'rounded-md': rounded === 'md',
182
+ 'rounded-lg': rounded === 'lg',
183
+ 'rounded-xl': rounded === 'xl',
184
+ 'rounded-2xl': rounded === '2xl',
185
+ 'rounded-3xl': rounded === '3xl',
186
+ 'rounded-full': rounded === 'full',
187
+ }
188
+ ),
189
+ placeholder: ({ isDisabled }) => cn('text-gray-500 text-base', isDisabled && 'opacity-50'),
190
+ loadingMessage: () => 'text-gray-500 text-base p-3',
191
+ noOptionsMessage: () => 'text-gray-500 text-base p-3',
192
+ input: ({ isDisabled }) => cn('text-gray-900 text-base', isDisabled && 'opacity-50'),
193
+ singleValue: ({ isDisabled }) => cn('text-gray-900 text-base', isDisabled && 'opacity-50'),
194
+ valueContainer: () => 'gap-1 flex flex-wrap',
195
+ multiValue: ({ isDisabled }) => cn(
196
+ 'flex items-center bg-white border border-gray-200 text-gray-700 rounded-[6px] pl-[9px] pr-[6px] py-[3px] text-sm font-medium leading-none',
197
+ isDisabled && 'opacity-50'
198
+ ),
199
+ multiValueLabel: ({ isDisabled }) => cn('text-base truncate max-w-[150px]', isDisabled && 'opacity-50'),
200
+ multiValueRemove: ({ isDisabled }) => cn(
201
+ 'ml-1 text-gray-400 hover:text-gray-600 cursor-pointer',
202
+ isDisabled && 'opacity-50 pointer-events-none'
203
+ ),
204
+ menu: () => 'bg-blur mt-2 rounded-md shadow-md z-50',
205
+ option: ({ isFocused, isSelected, isDisabled }) => cn(
206
+ 'cursor-pointer px-3 py-2 flex items-center gap-2 rounded-sm',
207
+ 'text-base font-semibold',
208
+ isSelected ? 'bg-white text-primary' : 'text-gray-900',
209
+ isFocused && 'bg-gray-100',
210
+ isDisabled && 'opacity-50 pointer-events-none cursor-not-allowed'
211
+ ),
212
+ indicatorsContainer: ({ isDisabled }) => cn(isDisabled && 'opacity-50'),
213
+ dropdownIndicator: ({ isDisabled }) => cn(
214
+ 'text-gray-400 cursor-pointer hover:text-gray-700',
215
+ isDisabled && 'opacity-50 pointer-events-none'
216
+ ),
217
+ clearIndicator: () => cn('text-gray-400 cursor-pointer hover:text-gray-700'),
218
+ };
219
+
220
+ return defaultClassNames;
221
+ };
222
+
223
+ export const Dropdown = <
224
+ OptionType extends OptionsType,
225
+ IsMulti extends boolean = false,
226
+ Group extends GroupBase<OptionType> = GroupBase<OptionType>,
227
+ >(
228
+ {
229
+ classNames,
230
+ components: customComponents,
231
+ placeholder,
232
+ creatable = false,
233
+ showSearchIcon = false,
234
+ size = 'md',
235
+ icon,
236
+ rounded = '2xl',
237
+ createLabel,
238
+ ...props
239
+ }: DropdownProps<OptionType, IsMulti, Group>
240
+ ) => {
241
+
242
+ let SelectComponent;
243
+
244
+ if (creatable) {
245
+ SelectComponent = CreatableSelect;
246
+ } else {
247
+ SelectComponent = Select;
248
+ }
249
+
250
+ return (
251
+ <SelectComponent<OptionType, IsMulti, Group>
252
+ {...props}
253
+ components={{
254
+ MultiValueLabel: CustomMultiValueLabel,
255
+ MultiValueContainer: CustomMultiValueContainer,
256
+ MultiValueRemove: CustomMultiValueRemove,
257
+ Control: (controlProps) => (
258
+ <CustomControl {...controlProps} showSearchIcon={showSearchIcon} icon={icon} />
259
+ ),
260
+ DropdownIndicator: CustomDropdownIndicator,
261
+ ClearIndicator: CustomClearIndicator,
262
+ Option: CustomOption,
263
+ LoadingIndicator: CustomLoadingIndicator,
264
+ ...customComponents,
265
+ }}
266
+ classNames={{
267
+ ...customClassNames(size, rounded),
268
+ ...classNames,
269
+ }}
270
+ unstyled
271
+ placeholder={placeholder || 'Selecione'}
272
+ formatCreateLabel={creatable ? (input) => <span className="text-primary font-medium flex items-center gap-2"><PlusCircle className="size-5" /> {createLabel ? `${createLabel} "${input}"` : `Criar "${input}"`}</span> : undefined}
273
+ noOptionsMessage={props.noOptionsMessage || (() => 'Nenhuma opção')}
274
+ loadingMessage={props.loadingMessage || (() => 'Carregando...')}
275
+ />
276
+ );
277
+ };
278
+
279
+ export const DropdownAsync = <
280
+ OptionType extends OptionsType,
281
+ IsMulti extends boolean = false,
282
+ Additional = { page: number },
283
+ Group extends GroupBase<OptionType> = GroupBase<OptionType>,
284
+ >(
285
+ {
286
+ classNames,
287
+ components: customComponents,
288
+ showSearchIcon = false,
289
+ size = 'md',
290
+ icon,
291
+ rounded = '2xl',
292
+ placeholder,
293
+ ...props
294
+ }: AsyncPaginateCreatableProps<OptionType, IsMulti, Additional, Group>
295
+ ) => {
296
+ return (
297
+ <AsyncPaginate
298
+ {...props}
299
+ components={{
300
+ MultiValueLabel: CustomMultiValueLabel,
301
+ MultiValueContainer: CustomMultiValueContainer,
302
+ MultiValueRemove: CustomMultiValueRemove,
303
+ Control: (controlProps) => (
304
+ <CustomControl {...controlProps} showSearchIcon={showSearchIcon} icon={icon} />
305
+ ),
306
+ DropdownIndicator: CustomDropdownIndicator,
307
+ ClearIndicator: CustomClearIndicator,
308
+ Option: CustomOption,
309
+ LoadingIndicator: CustomLoadingIndicator,
310
+ ...customComponents,
311
+ }}
312
+ classNames={{
313
+ ...(customClassNames(size, rounded) as ClassNamesConfig<OptionType, IsMulti, Group>),
314
+ ...classNames,
315
+ }}
316
+ unstyled
317
+ placeholder={placeholder || 'Selecione'}
318
+ noOptionsMessage={props.noOptionsMessage || (() => 'Nenhuma opção')}
319
+ loadingMessage={props.loadingMessage || (() => 'Carregando...')}
320
+ />
321
+ );
322
+ };
@@ -0,0 +1 @@
1
+ export * from './dropdown';