@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,314 @@
1
+ import * as React from 'react';
2
+
3
+ import * as MenubarPrimitive from '@radix-ui/react-menubar';
4
+ import { CheckIcon, ChevronRightIcon, CircleIcon } from 'lucide-react';
5
+
6
+ import { cn } from '@/utils/index';
7
+
8
+ function Menubar({
9
+ className,
10
+ ...props
11
+ }: React.ComponentProps<typeof MenubarPrimitive.Root>) {
12
+ return (
13
+ <MenubarPrimitive.Root
14
+ data-slot="menubar"
15
+ data-testid="menubar"
16
+ className={cn(
17
+ 'bg-background flex h-9 items-center gap-1 rounded-md border p-1 shadow-xs',
18
+ className
19
+ )}
20
+ {...props}
21
+ />
22
+ );
23
+ }
24
+
25
+ function MenubarMenu({
26
+ ...props
27
+ }: React.ComponentProps<typeof MenubarPrimitive.Menu>) {
28
+ return (
29
+ <MenubarPrimitive.Menu
30
+ data-slot="menubar-menu"
31
+ data-testid="menubar-menu"
32
+ {...props}
33
+ />
34
+ );
35
+ }
36
+
37
+ function MenubarGroup({
38
+ ...props
39
+ }: React.ComponentProps<typeof MenubarPrimitive.Group>) {
40
+ return (
41
+ <MenubarPrimitive.Group
42
+ data-slot="menubar-group"
43
+ data-testid="menubar-group"
44
+ {...props}
45
+ />
46
+ );
47
+ }
48
+
49
+ function MenubarPortal({
50
+ ...props
51
+ }: React.ComponentProps<typeof MenubarPrimitive.Portal>) {
52
+ return (
53
+ <MenubarPrimitive.Portal
54
+ data-slot="menubar-portal"
55
+ data-testid="menubar-portal"
56
+ {...props}
57
+ />
58
+ );
59
+ }
60
+
61
+ function MenubarRadioGroup({
62
+ ...props
63
+ }: React.ComponentProps<typeof MenubarPrimitive.RadioGroup>) {
64
+ return (
65
+ <MenubarPrimitive.RadioGroup
66
+ data-slot="menubar-radio-group"
67
+ data-testid="menubar-radio-group"
68
+ {...props}
69
+ />
70
+ );
71
+ }
72
+
73
+ function MenubarTrigger({
74
+ className,
75
+ ...props
76
+ }: React.ComponentProps<typeof MenubarPrimitive.Trigger>) {
77
+ return (
78
+ <MenubarPrimitive.Trigger
79
+ data-slot="menubar-trigger"
80
+ data-testid="menubar-trigger"
81
+ className={cn(
82
+ 'focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex items-center rounded-sm px-2 py-1 text-sm font-medium outline-hidden select-none',
83
+ className
84
+ )}
85
+ {...props}
86
+ />
87
+ );
88
+ }
89
+
90
+ function MenubarContent({
91
+ className,
92
+ align = 'start',
93
+ alignOffset = -4,
94
+ sideOffset = 8,
95
+ ...props
96
+ }: React.ComponentProps<typeof MenubarPrimitive.Content>) {
97
+ return (
98
+ <MenubarPortal>
99
+ <MenubarPrimitive.Content
100
+ data-slot="menubar-content"
101
+ data-testid="menubar-content"
102
+ align={align}
103
+ alignOffset={alignOffset}
104
+ sideOffset={sideOffset}
105
+ className={cn(
106
+ 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[12rem] origin-(--radix-menubar-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-md',
107
+ className
108
+ )}
109
+ {...props}
110
+ />
111
+ </MenubarPortal>
112
+ );
113
+ }
114
+
115
+ function MenubarItem({
116
+ className,
117
+ inset,
118
+ variant = 'default',
119
+ ...props
120
+ }: React.ComponentProps<typeof MenubarPrimitive.Item> & {
121
+ inset?: boolean
122
+ variant?: 'default' | 'destructive'
123
+ }) {
124
+ return (
125
+ <MenubarPrimitive.Item
126
+ data-slot="menubar-item"
127
+ data-testid="menubar-item"
128
+ data-inset={inset}
129
+ data-variant={variant}
130
+ className={cn(
131
+ 'focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*=\'text-\'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4',
132
+ className
133
+ )}
134
+ {...props}
135
+ />
136
+ );
137
+ }
138
+
139
+ function MenubarCheckboxItem({
140
+ className,
141
+ children,
142
+ checked,
143
+ ...props
144
+ }: React.ComponentProps<typeof MenubarPrimitive.CheckboxItem>) {
145
+ return (
146
+ <MenubarPrimitive.CheckboxItem
147
+ data-slot="menubar-checkbox-item"
148
+ data-testid="menubar-checkbox-item"
149
+ className={cn(
150
+ 'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4',
151
+ className
152
+ )}
153
+ checked={checked}
154
+ {...props}
155
+ >
156
+ <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
157
+ <MenubarPrimitive.ItemIndicator>
158
+ <CheckIcon className="size-4" />
159
+ </MenubarPrimitive.ItemIndicator>
160
+ </span>
161
+ {children}
162
+ </MenubarPrimitive.CheckboxItem>
163
+ );
164
+ }
165
+
166
+ function MenubarRadioItem({
167
+ className,
168
+ children,
169
+ ...props
170
+ }: React.ComponentProps<typeof MenubarPrimitive.RadioItem>) {
171
+ return (
172
+ <MenubarPrimitive.RadioItem
173
+ data-slot="menubar-radio-item"
174
+ data-testid="menubar-radio-item"
175
+ className={cn(
176
+ 'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4',
177
+ className
178
+ )}
179
+ {...props}
180
+ >
181
+ <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
182
+ <MenubarPrimitive.ItemIndicator>
183
+ <CircleIcon className="size-2 fill-current" />
184
+ </MenubarPrimitive.ItemIndicator>
185
+ </span>
186
+ {children}
187
+ </MenubarPrimitive.RadioItem>
188
+ );
189
+ }
190
+
191
+ function MenubarLabel({
192
+ className,
193
+ inset,
194
+ ...props
195
+ }: React.ComponentProps<typeof MenubarPrimitive.Label> & {
196
+ inset?: boolean
197
+ }) {
198
+ return (
199
+ <MenubarPrimitive.Label
200
+ data-slot="menubar-label"
201
+ data-testid="menubar-label"
202
+ data-inset={inset}
203
+ className={cn(
204
+ 'px-2 py-1.5 text-sm font-medium data-[inset]:pl-8',
205
+ className
206
+ )}
207
+ {...props}
208
+ />
209
+ );
210
+ }
211
+
212
+ function MenubarSeparator({
213
+ className,
214
+ ...props
215
+ }: React.ComponentProps<typeof MenubarPrimitive.Separator>) {
216
+ return (
217
+ <MenubarPrimitive.Separator
218
+ data-slot="menubar-separator"
219
+ data-testid="menubar-separator"
220
+ className={cn('bg-border -mx-1 my-1 h-px', className)}
221
+ {...props}
222
+ />
223
+ );
224
+ }
225
+
226
+ function MenubarShortcut({
227
+ className,
228
+ ...props
229
+ }: React.ComponentProps<'span'>) {
230
+ return (
231
+ <span
232
+ data-slot="menubar-shortcut"
233
+ data-testid="menubar-shortcut"
234
+ className={cn(
235
+ 'text-muted-foreground ml-auto text-xs tracking-widest',
236
+ className
237
+ )}
238
+ {...props}
239
+ />
240
+ );
241
+ }
242
+
243
+ function MenubarSub({
244
+ ...props
245
+ }: React.ComponentProps<typeof MenubarPrimitive.Sub>) {
246
+ return (
247
+ <MenubarPrimitive.Sub
248
+ data-slot="menubar-sub"
249
+ data-testid="menubar-sub"
250
+ {...props}
251
+ />
252
+ );
253
+ }
254
+
255
+ function MenubarSubTrigger({
256
+ className,
257
+ inset,
258
+ children,
259
+ ...props
260
+ }: React.ComponentProps<typeof MenubarPrimitive.SubTrigger> & {
261
+ inset?: boolean
262
+ }) {
263
+ return (
264
+ <MenubarPrimitive.SubTrigger
265
+ data-slot="menubar-sub-trigger"
266
+ data-testid="menubar-sub-trigger"
267
+ data-inset={inset}
268
+ className={cn(
269
+ 'focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[inset]:pl-8',
270
+ className
271
+ )}
272
+ {...props}
273
+ >
274
+ {children}
275
+ <ChevronRightIcon className="ml-auto h-4 w-4" />
276
+ </MenubarPrimitive.SubTrigger>
277
+ );
278
+ }
279
+
280
+ function MenubarSubContent({
281
+ className,
282
+ ...props
283
+ }: React.ComponentProps<typeof MenubarPrimitive.SubContent>) {
284
+ return (
285
+ <MenubarPrimitive.SubContent
286
+ data-slot="menubar-sub-content"
287
+ data-testid="menubar-sub-content"
288
+ className={cn(
289
+ 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-menubar-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg',
290
+ className
291
+ )}
292
+ {...props}
293
+ />
294
+ );
295
+ }
296
+
297
+ export {
298
+ Menubar,
299
+ MenubarCheckboxItem,
300
+ MenubarContent,
301
+ MenubarGroup,
302
+ MenubarItem,
303
+ MenubarLabel,
304
+ MenubarMenu,
305
+ MenubarPortal,
306
+ MenubarRadioGroup,
307
+ MenubarRadioItem,
308
+ MenubarSeparator,
309
+ MenubarShortcut,
310
+ MenubarSub,
311
+ MenubarSubContent,
312
+ MenubarSubTrigger,
313
+ MenubarTrigger,
314
+ };
@@ -0,0 +1 @@
1
+ export * from './navigation-menu';
@@ -0,0 +1,143 @@
1
+ import {
2
+ NavigationMenu,
3
+ NavigationMenuList,
4
+ NavigationMenuItem,
5
+ NavigationMenuTrigger,
6
+ NavigationMenuContent,
7
+ NavigationMenuLink,
8
+ NavigationMenuIndicator,
9
+ NavigationMenuViewport,
10
+ } from './navigation-menu';
11
+
12
+ import type { Meta, StoryObj } from '@storybook/react';
13
+
14
+ const meta: Meta<typeof NavigationMenu> = {
15
+ title: 'Components/Navigation/NavigationMenu',
16
+ component: NavigationMenu,
17
+ tags: [ 'autodocs' ],
18
+ parameters: {
19
+ layout: 'centered',
20
+ docs: {
21
+ description: {
22
+ component: `
23
+ The NavigationMenu component is a fully accessible and animated horizontal menu created with the Radix UI. It supports advanced content dropdown menus, focus and click interactions, and an optional viewport window for advanced dropdown menu positioning.
24
+
25
+ This component is ideal for top-level navigation with dropdown menus in web applications, especially those that need flexible and responsive content layouts.
26
+ `,
27
+ },
28
+ },
29
+ },
30
+ };
31
+
32
+ export default meta;
33
+ type Story = StoryObj<typeof NavigationMenu>;
34
+
35
+ export const Default: Story = {
36
+ name: 'Default',
37
+ parameters: {
38
+ docs: {
39
+ description: {
40
+ story: 'A basic NavigationMenu with a trigger and content panel.',
41
+ },
42
+ },
43
+ },
44
+ render: () => (
45
+ <NavigationMenu>
46
+ <NavigationMenuList>
47
+ <NavigationMenuItem>
48
+ <NavigationMenuTrigger>Products</NavigationMenuTrigger>
49
+ <NavigationMenuContent>
50
+ <ul className="grid w-[300px] gap-3 p-4 md:w-[400px] md:grid-cols-2 lg:w-[500px]">
51
+ <li>
52
+ <NavigationMenuLink href="#">
53
+ Product A
54
+ <p className="text-muted-foreground text-xs">
55
+ Description for product A.
56
+ </p>
57
+ </NavigationMenuLink>
58
+ </li>
59
+ <li>
60
+ <NavigationMenuLink href="#">
61
+ Product B
62
+ <p className="text-muted-foreground text-xs">
63
+ Description for product B.
64
+ </p>
65
+ </NavigationMenuLink>
66
+ </li>
67
+ </ul>
68
+ </NavigationMenuContent>
69
+ </NavigationMenuItem>
70
+ </NavigationMenuList>
71
+ </NavigationMenu>
72
+ ),
73
+ };
74
+
75
+ export const WithIndicatorAndViewport: Story = {
76
+ name: 'With Indicator and Viewport',
77
+ parameters: {
78
+ docs: {
79
+ description: {
80
+ story:
81
+ 'This example demonstrates the features of the indicator and viewport enabled by default.',
82
+ },
83
+ },
84
+ },
85
+ render: () => (
86
+ <NavigationMenu>
87
+ <NavigationMenuList>
88
+ <NavigationMenuItem>
89
+ <NavigationMenuTrigger>Resources</NavigationMenuTrigger>
90
+ <NavigationMenuContent>
91
+ <ul className="grid w-[300px] gap-3 p-4 md:w-[400px] md:grid-cols-2 lg:w-[500px]">
92
+ <li>
93
+ <NavigationMenuLink href="#">
94
+ Docs
95
+ <p className="text-muted-foreground text-xs">
96
+ Developer documentation and API.
97
+ </p>
98
+ </NavigationMenuLink>
99
+ </li>
100
+ <li>
101
+ <NavigationMenuLink href="#">
102
+ Community
103
+ <p className="text-muted-foreground text-xs">
104
+ Forums and support channels.
105
+ </p>
106
+ </NavigationMenuLink>
107
+ </li>
108
+ </ul>
109
+ </NavigationMenuContent>
110
+ </NavigationMenuItem>
111
+ <NavigationMenuIndicator />
112
+ </NavigationMenuList>
113
+ <NavigationMenuViewport />
114
+ </NavigationMenu>
115
+ ),
116
+ };
117
+
118
+ export const WithoutViewport: Story = {
119
+ name: 'Without Viewport',
120
+ parameters: {
121
+ docs: {
122
+ description: {
123
+ story:
124
+ 'If you prefer not to use the animated viewport wrapper, you can disable it via the `viewport={false}` prop.',
125
+ },
126
+ },
127
+ },
128
+ render: () => (
129
+ <NavigationMenu viewport={false}>
130
+ <NavigationMenuList>
131
+ <NavigationMenuItem>
132
+ <NavigationMenuTrigger>Company</NavigationMenuTrigger>
133
+ <NavigationMenuContent>
134
+ <div className="p-4 w-[300px]">
135
+ <NavigationMenuLink href="#">About us</NavigationMenuLink>
136
+ <NavigationMenuLink href="#">Careers</NavigationMenuLink>
137
+ </div>
138
+ </NavigationMenuContent>
139
+ </NavigationMenuItem>
140
+ </NavigationMenuList>
141
+ </NavigationMenu>
142
+ ),
143
+ };
@@ -0,0 +1,69 @@
1
+ import { fireEvent, render, screen } from '@testing-library/react';
2
+ import { describe, expect, it } from 'vitest';
3
+
4
+ import {
5
+ NavigationMenu,
6
+ NavigationMenuContent,
7
+ NavigationMenuIndicator,
8
+ NavigationMenuItem,
9
+ NavigationMenuLink,
10
+ NavigationMenuList,
11
+ NavigationMenuTrigger,
12
+ } from './navigation-menu';
13
+
14
+ function renderNavigationMenu(props = {}) {
15
+ render(
16
+ <NavigationMenu {...props}>
17
+ <NavigationMenuList>
18
+ <NavigationMenuItem>
19
+ <NavigationMenuTrigger>
20
+ Menu
21
+ <span data-testid="chevron-icon" />
22
+ </NavigationMenuTrigger>
23
+ <NavigationMenuContent>
24
+ <NavigationMenuLink href="/">Home</NavigationMenuLink>
25
+ </NavigationMenuContent>
26
+ </NavigationMenuItem>
27
+ <NavigationMenuIndicator />
28
+ </NavigationMenuList>
29
+ </NavigationMenu>
30
+ );
31
+ }
32
+
33
+ describe('<NavigationMenu />', () => {
34
+ it('renders root menu with viewport by default', () => {
35
+ renderNavigationMenu();
36
+ expect(screen.getByTestId('navigation-menu')).toBeInTheDocument();
37
+ expect(screen.getByTestId('navigation-menu-viewport')).toBeInTheDocument();
38
+ });
39
+
40
+ it('does not render viewport when disabled', () => {
41
+ renderNavigationMenu({ viewport: false });
42
+ expect(screen.queryByTestId('navigation-menu-viewport')).not.toBeInTheDocument();
43
+ });
44
+
45
+ it('renders menu trigger with icon', () => {
46
+ renderNavigationMenu();
47
+ expect(screen.getByTestId('navigation-menu-trigger')).toBeInTheDocument();
48
+ expect(screen.getByTestId('chevron-icon')).toBeInTheDocument();
49
+ });
50
+
51
+ it('toggles content visibility when trigger is clicked', () => {
52
+ renderNavigationMenu();
53
+ const trigger = screen.getByTestId('navigation-menu-trigger');
54
+
55
+ fireEvent.click(trigger);
56
+ expect(screen.getByTestId('navigation-menu-content')).toBeVisible();
57
+ });
58
+
59
+ it('renders custom link inside content', () => {
60
+ renderNavigationMenu();
61
+ fireEvent.click(screen.getByTestId('navigation-menu-trigger'));
62
+ expect(screen.getByRole('link', { name: /home/i })).toBeInTheDocument();
63
+ });
64
+
65
+ it('should match snapshot', () => {
66
+ const { container } = render(<NavigationMenu />);
67
+ expect(container).toMatchSnapshot();
68
+ });
69
+ });
@@ -0,0 +1,174 @@
1
+ /* eslint-disable react-refresh/only-export-components */
2
+ import * as React from 'react';
3
+
4
+ import * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu';
5
+ import { cva } from 'class-variance-authority';
6
+ import { ChevronDownIcon } from 'lucide-react';
7
+
8
+ import { cn } from '@/utils/index';
9
+
10
+ function NavigationMenu ({
11
+ className,
12
+ children,
13
+ viewport = true,
14
+ ...props
15
+ }: React.ComponentProps<typeof NavigationMenuPrimitive.Root> & {
16
+ viewport?: boolean;
17
+ }) {
18
+ return (
19
+ <NavigationMenuPrimitive.Root
20
+ data-slot="navigation-menu"
21
+ data-testid="navigation-menu"
22
+ data-viewport={viewport}
23
+ className={cn(
24
+ 'group/navigation-menu relative flex max-w-max flex-1 items-center justify-center',
25
+ className
26
+ )}
27
+ {...props}
28
+ >
29
+ {children}
30
+ {viewport && <NavigationMenuViewport />}
31
+ </NavigationMenuPrimitive.Root>
32
+ );
33
+ }
34
+
35
+ function NavigationMenuList ({
36
+ className,
37
+ ...props
38
+ }: React.ComponentProps<typeof NavigationMenuPrimitive.List>) {
39
+ return (
40
+ <NavigationMenuPrimitive.List
41
+ data-slot="navigation-menu-list"
42
+ className={cn(
43
+ 'group flex flex-1 list-none items-center justify-center gap-1',
44
+ className
45
+ )}
46
+ {...props}
47
+ />
48
+ );
49
+ }
50
+
51
+ function NavigationMenuItem ({
52
+ className,
53
+ ...props
54
+ }: React.ComponentProps<typeof NavigationMenuPrimitive.Item>) {
55
+ return (
56
+ <NavigationMenuPrimitive.Item
57
+ data-slot="navigation-menu-item"
58
+ className={cn('relative', className)}
59
+ {...props}
60
+ />
61
+ );
62
+ }
63
+
64
+ const navigationMenuTriggerStyle = cva(
65
+ 'group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-3 py-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=open]:hover:bg-accent data-[state=open]:text-accent-foreground data-[state=open]:focus:bg-accent data-[state=open]:bg-accent/50 focus-visible:ring-ring/50 outline-none transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1'
66
+ );
67
+
68
+ function NavigationMenuTrigger ({
69
+ className,
70
+ children,
71
+ ...props
72
+ }: React.ComponentProps<typeof NavigationMenuPrimitive.Trigger>) {
73
+ return (
74
+ <NavigationMenuPrimitive.Trigger
75
+ data-slot="navigation-menu-trigger"
76
+ data-testid="navigation-menu-trigger"
77
+ className={cn(navigationMenuTriggerStyle(), 'group', className)}
78
+ {...props}
79
+ >
80
+ {children}{' '}
81
+ <ChevronDownIcon
82
+ className="relative top-[1px] ml-3 transition duration-300 text-gray-400 group-data-[state=open]:rotate-180 size-4"
83
+ aria-hidden="true"
84
+ />
85
+ </NavigationMenuPrimitive.Trigger>
86
+ );
87
+ }
88
+
89
+ function NavigationMenuContent ({
90
+ className,
91
+ ...props
92
+ }: React.ComponentProps<typeof NavigationMenuPrimitive.Content>) {
93
+ return (
94
+ <NavigationMenuPrimitive.Content
95
+ data-slot="navigation-menu-content"
96
+ data-testid="navigation-menu-content"
97
+ className={cn(
98
+ 'data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 top-0 left-0 w-full p-2 pr-2.5 md:absolute md:w-auto',
99
+ 'group-data-[viewport=false]/navigation-menu:bg-popover group-data-[viewport=false]/navigation-menu:text-popover-foreground group-data-[viewport=false]/navigation-menu:data-[state=open]:animate-in group-data-[viewport=false]/navigation-menu:data-[state=closed]:animate-out group-data-[viewport=false]/navigation-menu:data-[state=closed]:zoom-out-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:zoom-in-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:fade-in-0 group-data-[viewport=false]/navigation-menu:data-[state=closed]:fade-out-0 group-data-[viewport=false]/navigation-menu:top-full group-data-[viewport=false]/navigation-menu:mt-1.5 group-data-[viewport=false]/navigation-menu:overflow-hidden group-data-[viewport=false]/navigation-menu:rounded-md group-data-[viewport=false]/navigation-menu:border group-data-[viewport=false]/navigation-menu:shadow group-data-[viewport=false]/navigation-menu:duration-200 **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-none',
100
+ className
101
+ )}
102
+ {...props}
103
+ />
104
+ );
105
+ }
106
+
107
+ function NavigationMenuViewport ({
108
+ className,
109
+ ...props
110
+ }: React.ComponentProps<typeof NavigationMenuPrimitive.Viewport>) {
111
+ return (
112
+ <div
113
+ className={cn('absolute top-full isolate z-50 flex justify-center')}
114
+ data-testid="navigation-menu-viewport"
115
+ >
116
+ <NavigationMenuPrimitive.Viewport
117
+ data-slot="navigation-menu-viewport"
118
+ className={cn(
119
+ 'origin-top-center bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border shadow md:w-[var(--radix-navigation-menu-viewport-width)]',
120
+ className
121
+ )}
122
+ {...props}
123
+ />
124
+ </div>
125
+ );
126
+ }
127
+
128
+ function NavigationMenuLink ({
129
+ className,
130
+ ...props
131
+ }: React.ComponentProps<typeof NavigationMenuPrimitive.Link>) {
132
+ return (
133
+ <NavigationMenuPrimitive.Link
134
+ data-slot="navigation-menu-link"
135
+ data-testid="navigation-menu-link"
136
+ className={cn(
137
+ 'data-[active=true]:focus:bg-accent data-[active=true]:hover:bg-accent data-[active=true]:bg-accent/50 data-[active=true]:text-accent-foreground hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus-visible:ring-ring/50 [&_svg:not([class*=\'text-\'])]:text-muted-foreground flex flex-col gap-3 rounded-sm p-2 text-sm transition-all outline-none focus-visible:ring-[3px] focus-visible:outline-1 [&_svg:not([class*=\'size-\'])]:size-4',
138
+ className
139
+ )}
140
+ {...props}
141
+ />
142
+ );
143
+ }
144
+
145
+ function NavigationMenuIndicator ({
146
+ className,
147
+ ...props
148
+ }: React.ComponentProps<typeof NavigationMenuPrimitive.Indicator>) {
149
+ return (
150
+ <NavigationMenuPrimitive.Indicator
151
+ data-slot="navigation-menu-indicator"
152
+ data-testid="navigation-menu-indicator"
153
+ className={cn(
154
+ 'data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden',
155
+ className
156
+ )}
157
+ {...props}
158
+ >
159
+ <div className="bg-border relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm shadow-md" />
160
+ </NavigationMenuPrimitive.Indicator>
161
+ );
162
+ }
163
+
164
+ export {
165
+ NavigationMenu,
166
+ NavigationMenuContent,
167
+ NavigationMenuIndicator,
168
+ NavigationMenuItem,
169
+ NavigationMenuLink,
170
+ NavigationMenuList,
171
+ NavigationMenuTrigger,
172
+ navigationMenuTriggerStyle,
173
+ NavigationMenuViewport,
174
+ };