@12-apps/ui 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (633) hide show
  1. package/components-catalog.md +806 -0
  2. package/components-guidelines.md +347 -0
  3. package/dist/index.cjs +2 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +2 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +1 -0
  8. package/dist/index.js.map +1 -0
  9. package/eslint.config.js +77 -0
  10. package/package.json +247 -0
  11. package/src/__tests__/package-wiring.test.ts +37 -0
  12. package/src/__tests__/setup.ts +1 -0
  13. package/src/__tests__/social-login-button.test.tsx +186 -0
  14. package/src/__tests__/user-avatar.test.tsx +195 -0
  15. package/src/button.tsx +22 -0
  16. package/src/components/command/__tests__/command.test.tsx +112 -0
  17. package/src/components/data-display/Alert/Alert.md +209 -0
  18. package/src/components/data-display/Alert/Alert.stories.tsx +561 -0
  19. package/src/components/data-display/Alert/Alert.test.stories.tsx +709 -0
  20. package/src/components/data-display/Alert/Alert.tsx +449 -0
  21. package/src/components/data-display/Alert/Alert.types.ts +79 -0
  22. package/src/components/data-display/Alert/index.ts +2 -0
  23. package/src/components/data-display/AlertDialog/AlertDialog.md +408 -0
  24. package/src/components/data-display/AlertDialog/AlertDialog.stories.tsx +360 -0
  25. package/src/components/data-display/AlertDialog/AlertDialog.test.stories.tsx +753 -0
  26. package/src/components/data-display/AlertDialog/AlertDialog.tsx +273 -0
  27. package/src/components/data-display/AlertDialog/AlertDialog.types.ts +74 -0
  28. package/src/components/data-display/AlertDialog/index.ts +2 -0
  29. package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.stories.tsx +230 -0
  30. package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.test.stories.tsx +270 -0
  31. package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.tsx +116 -0
  32. package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.types.ts +70 -0
  33. package/src/components/data-display/AsyncStateContainer/index.ts +2 -0
  34. package/src/components/data-display/Avatar/Avatar.md +568 -0
  35. package/src/components/data-display/Avatar/Avatar.stories.tsx +718 -0
  36. package/src/components/data-display/Avatar/Avatar.test.stories.tsx +820 -0
  37. package/src/components/data-display/Avatar/Avatar.tsx +507 -0
  38. package/src/components/data-display/Avatar/Avatar.types.ts +88 -0
  39. package/src/components/data-display/Avatar/index.ts +2 -0
  40. package/src/components/data-display/Badge/Badge.md +469 -0
  41. package/src/components/data-display/Badge/Badge.stories.tsx +1136 -0
  42. package/src/components/data-display/Badge/Badge.test.stories.tsx +1193 -0
  43. package/src/components/data-display/Badge/Badge.tsx +606 -0
  44. package/src/components/data-display/Badge/Badge.types.ts +118 -0
  45. package/src/components/data-display/Badge/index.ts +2 -0
  46. package/src/components/data-display/Banner/Banner.stories.tsx +524 -0
  47. package/src/components/data-display/Banner/Banner.test.stories.tsx +503 -0
  48. package/src/components/data-display/Banner/Banner.tsx +350 -0
  49. package/src/components/data-display/Banner/Banner.types.ts +41 -0
  50. package/src/components/data-display/Banner/banner.md +141 -0
  51. package/src/components/data-display/Banner/index.ts +2 -0
  52. package/src/components/data-display/Carousel/Carousel.md +815 -0
  53. package/src/components/data-display/Carousel/Carousel.stories.tsx +607 -0
  54. package/src/components/data-display/Carousel/Carousel.test.stories.tsx +691 -0
  55. package/src/components/data-display/Carousel/Carousel.tsx +765 -0
  56. package/src/components/data-display/Carousel/Carousel.types.ts +79 -0
  57. package/src/components/data-display/Carousel/index.ts +8 -0
  58. package/src/components/data-display/Chart/Chart.md +352 -0
  59. package/src/components/data-display/Chart/Chart.stories.tsx +568 -0
  60. package/src/components/data-display/Chart/Chart.test.stories.tsx +174 -0
  61. package/src/components/data-display/Chart/Chart.tsx +520 -0
  62. package/src/components/data-display/Chart/Chart.types.ts +65 -0
  63. package/src/components/data-display/Chart/index.ts +2 -0
  64. package/src/components/data-display/Chip/Chip.stories.tsx +251 -0
  65. package/src/components/data-display/Chip/Chip.test.stories.tsx +263 -0
  66. package/src/components/data-display/Chip/Chip.tsx +134 -0
  67. package/src/components/data-display/Chip/Chip.types.ts +51 -0
  68. package/src/components/data-display/Chip/chip.md +395 -0
  69. package/src/components/data-display/Chip/index.ts +2 -0
  70. package/src/components/data-display/DataGrid/DataGrid.md +602 -0
  71. package/src/components/data-display/DataGrid/DataGrid.stories.tsx +515 -0
  72. package/src/components/data-display/DataGrid/DataGrid.test.stories.tsx +659 -0
  73. package/src/components/data-display/DataGrid/DataGrid.tsx +743 -0
  74. package/src/components/data-display/DataGrid/DataGrid.types.ts +171 -0
  75. package/src/components/data-display/DataGrid/index.ts +21 -0
  76. package/src/components/data-display/DateTimeDisplay/DateTimeDisplay.tsx +197 -0
  77. package/src/components/data-display/DateTimeDisplay/DateTimeDisplay.types.ts +46 -0
  78. package/src/components/data-display/DateTimeDisplay/index.ts +2 -0
  79. package/src/components/data-display/DescriptionItem/DescriptionItem.md +226 -0
  80. package/src/components/data-display/DescriptionItem/DescriptionItem.stories.tsx +254 -0
  81. package/src/components/data-display/DescriptionItem/DescriptionItem.tsx +100 -0
  82. package/src/components/data-display/DescriptionItem/DescriptionItem.types.ts +1 -0
  83. package/src/components/data-display/DescriptionItem/index.ts +2 -0
  84. package/src/components/data-display/EmptyState/EmptyState.md +265 -0
  85. package/src/components/data-display/EmptyState/EmptyState.stories.tsx +282 -0
  86. package/src/components/data-display/EmptyState/EmptyState.test.stories.tsx +441 -0
  87. package/src/components/data-display/EmptyState/EmptyState.tsx +180 -0
  88. package/src/components/data-display/EmptyState/EmptyState.types.ts +31 -0
  89. package/src/components/data-display/EmptyState/index.ts +2 -0
  90. package/src/components/data-display/ErrorState/ErrorState.stories.tsx +110 -0
  91. package/src/components/data-display/ErrorState/ErrorState.test.stories.tsx +133 -0
  92. package/src/components/data-display/ErrorState/ErrorState.tsx +118 -0
  93. package/src/components/data-display/ErrorState/ErrorState.types.ts +45 -0
  94. package/src/components/data-display/ErrorState/index.ts +2 -0
  95. package/src/components/data-display/HoverCard/HoverCard.md +389 -0
  96. package/src/components/data-display/HoverCard/HoverCard.stories.tsx +648 -0
  97. package/src/components/data-display/HoverCard/HoverCard.test.stories.tsx +929 -0
  98. package/src/components/data-display/HoverCard/HoverCard.tsx +657 -0
  99. package/src/components/data-display/HoverCard/HoverCard.types.ts +116 -0
  100. package/src/components/data-display/HoverCard/index.ts +2 -0
  101. package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.md +532 -0
  102. package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.stories.tsx +411 -0
  103. package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.tsx +245 -0
  104. package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.types.ts +64 -0
  105. package/src/components/data-display/InteractiveTooltip/index.ts +2 -0
  106. package/src/components/data-display/LazyImage/LazyImage.md +356 -0
  107. package/src/components/data-display/LazyImage/LazyImage.stories.tsx +387 -0
  108. package/src/components/data-display/LazyImage/LazyImage.tsx +323 -0
  109. package/src/components/data-display/LazyImage/LazyImage.types.ts +205 -0
  110. package/src/components/data-display/LazyImage/index.ts +2 -0
  111. package/src/components/data-display/Lightbox/Lightbox.stories.tsx +315 -0
  112. package/src/components/data-display/Lightbox/Lightbox.test.stories.tsx +605 -0
  113. package/src/components/data-display/Lightbox/Lightbox.tsx +666 -0
  114. package/src/components/data-display/Lightbox/Lightbox.types.ts +49 -0
  115. package/src/components/data-display/Lightbox/index.ts +2 -0
  116. package/src/components/data-display/Lightbox/lightbox.md +298 -0
  117. package/src/components/data-display/LoadingState/LoadingState.stories.tsx +124 -0
  118. package/src/components/data-display/LoadingState/LoadingState.test.stories.tsx +99 -0
  119. package/src/components/data-display/LoadingState/LoadingState.tsx +103 -0
  120. package/src/components/data-display/LoadingState/LoadingState.types.ts +37 -0
  121. package/src/components/data-display/LoadingState/index.ts +2 -0
  122. package/src/components/data-display/MapPreview/MapPreview.md +154 -0
  123. package/src/components/data-display/MapPreview/MapPreview.stories.tsx +458 -0
  124. package/src/components/data-display/MapPreview/MapPreview.test.stories.tsx +390 -0
  125. package/src/components/data-display/MapPreview/MapPreview.tsx +922 -0
  126. package/src/components/data-display/MapPreview/MapPreview.types.ts +56 -0
  127. package/src/components/data-display/MapPreview/index.ts +2 -0
  128. package/src/components/data-display/Popover/Popover.md +245 -0
  129. package/src/components/data-display/Popover/Popover.stories.tsx +295 -0
  130. package/src/components/data-display/Popover/Popover.test.stories.tsx +1168 -0
  131. package/src/components/data-display/Popover/Popover.tsx +132 -0
  132. package/src/components/data-display/Popover/Popover.types.ts +33 -0
  133. package/src/components/data-display/Popover/index.ts +2 -0
  134. package/src/components/data-display/Progress/Progress.md +450 -0
  135. package/src/components/data-display/Progress/Progress.stories.tsx +481 -0
  136. package/src/components/data-display/Progress/Progress.test.stories.tsx +2070 -0
  137. package/src/components/data-display/Progress/Progress.tsx +332 -0
  138. package/src/components/data-display/Progress/Progress.types.ts +61 -0
  139. package/src/components/data-display/Progress/index.ts +2 -0
  140. package/src/components/data-display/SectionOnboarding/SectionOnboarding.md +108 -0
  141. package/src/components/data-display/SectionOnboarding/SectionOnboarding.stories.tsx +160 -0
  142. package/src/components/data-display/SectionOnboarding/SectionOnboarding.test.stories.tsx +190 -0
  143. package/src/components/data-display/SectionOnboarding/SectionOnboarding.tsx +224 -0
  144. package/src/components/data-display/SectionOnboarding/SectionOnboarding.types.ts +101 -0
  145. package/src/components/data-display/SectionOnboarding/index.ts +7 -0
  146. package/src/components/data-display/Sheet/Sheet.md +475 -0
  147. package/src/components/data-display/Sheet/Sheet.stories.tsx +883 -0
  148. package/src/components/data-display/Sheet/Sheet.test.stories.tsx +1101 -0
  149. package/src/components/data-display/Sheet/Sheet.tsx +978 -0
  150. package/src/components/data-display/Sheet/Sheet.types.ts +93 -0
  151. package/src/components/data-display/Sheet/index.ts +8 -0
  152. package/src/components/data-display/Stepper/Stepper.md +542 -0
  153. package/src/components/data-display/Stepper/Stepper.stories.tsx +540 -0
  154. package/src/components/data-display/Stepper/Stepper.test.stories.tsx +607 -0
  155. package/src/components/data-display/Stepper/Stepper.tsx +328 -0
  156. package/src/components/data-display/Stepper/Stepper.types.ts +97 -0
  157. package/src/components/data-display/Stepper/index.ts +2 -0
  158. package/src/components/data-display/Table/Table.md +243 -0
  159. package/src/components/data-display/Table/Table.stories.tsx +801 -0
  160. package/src/components/data-display/Table/Table.test.stories.tsx +369 -0
  161. package/src/components/data-display/Table/Table.tsx +831 -0
  162. package/src/components/data-display/Table/Table.types.ts +335 -0
  163. package/src/components/data-display/Table/index.ts +2 -0
  164. package/src/components/data-display/Timeline/Timeline.md +201 -0
  165. package/src/components/data-display/Timeline/Timeline.stories.tsx +444 -0
  166. package/src/components/data-display/Timeline/Timeline.test.stories.tsx +944 -0
  167. package/src/components/data-display/Timeline/Timeline.tsx +348 -0
  168. package/src/components/data-display/Timeline/Timeline.types.ts +26 -0
  169. package/src/components/data-display/Timeline/index.ts +2 -0
  170. package/src/components/data-display/TimingDiagram/TimingDiagram.md +162 -0
  171. package/src/components/data-display/TimingDiagram/TimingDiagram.stories.tsx +475 -0
  172. package/src/components/data-display/TimingDiagram/TimingDiagram.test.stories.tsx +734 -0
  173. package/src/components/data-display/TimingDiagram/TimingDiagram.tsx +399 -0
  174. package/src/components/data-display/TimingDiagram/TimingDiagram.types.ts +19 -0
  175. package/src/components/data-display/TimingDiagram/index.ts +2 -0
  176. package/src/components/data-display/Tooltip/Tooltip.md +397 -0
  177. package/src/components/data-display/Tooltip/Tooltip.stories.tsx +465 -0
  178. package/src/components/data-display/Tooltip/Tooltip.test.stories.tsx +1168 -0
  179. package/src/components/data-display/Tooltip/Tooltip.tsx +161 -0
  180. package/src/components/data-display/Tooltip/Tooltip.types.ts +33 -0
  181. package/src/components/data-display/Tooltip/index.ts +2 -0
  182. package/src/components/data-display/index.ts +29 -0
  183. package/src/components/feedback/Dialog/Dialog.md +527 -0
  184. package/src/components/feedback/Dialog/Dialog.stories.tsx +833 -0
  185. package/src/components/feedback/Dialog/Dialog.styles.ts +171 -0
  186. package/src/components/feedback/Dialog/Dialog.test.stories.tsx +955 -0
  187. package/src/components/feedback/Dialog/Dialog.tsx +256 -0
  188. package/src/components/feedback/Dialog/Dialog.types.ts +46 -0
  189. package/src/components/feedback/Dialog/index.ts +9 -0
  190. package/src/components/feedback/Modal/Modal.md +629 -0
  191. package/src/components/feedback/Modal/Modal.stories.tsx +765 -0
  192. package/src/components/feedback/Modal/Modal.test.stories.tsx +251 -0
  193. package/src/components/feedback/Modal/Modal.tsx +279 -0
  194. package/src/components/feedback/Modal/Modal.types.ts +26 -0
  195. package/src/components/feedback/Modal/index.ts +7 -0
  196. package/src/components/feedback/Sonner/Sonner.stories.tsx +698 -0
  197. package/src/components/feedback/Sonner/Sonner.test.stories.tsx +896 -0
  198. package/src/components/feedback/Sonner/Sonner.tsx +493 -0
  199. package/src/components/feedback/Sonner/Sonner.types.ts +65 -0
  200. package/src/components/feedback/Sonner/index.ts +8 -0
  201. package/src/components/feedback/StackedModal/StackedModal.md +273 -0
  202. package/src/components/feedback/StackedModal/StackedModal.stories.tsx +1785 -0
  203. package/src/components/feedback/StackedModal/StackedModal.test.stories.tsx +975 -0
  204. package/src/components/feedback/StackedModal/StackedModal.tsx +664 -0
  205. package/src/components/feedback/StackedModal/StackedModal.types.ts +70 -0
  206. package/src/components/feedback/StackedModal/index.ts +11 -0
  207. package/src/components/feedback/Toast/Toast.md +547 -0
  208. package/src/components/feedback/Toast/Toast.stories.tsx +548 -0
  209. package/src/components/feedback/Toast/Toast.test.stories.tsx +834 -0
  210. package/src/components/feedback/Toast/Toast.tsx +279 -0
  211. package/src/components/feedback/Toast/Toast.types.ts +59 -0
  212. package/src/components/feedback/Toast/index.ts +8 -0
  213. package/src/components/feedback/TutorialOverlay/TutorialOverlay.md +610 -0
  214. package/src/components/feedback/TutorialOverlay/TutorialOverlay.stories.tsx +691 -0
  215. package/src/components/feedback/TutorialOverlay/TutorialOverlay.test.stories.tsx +634 -0
  216. package/src/components/feedback/TutorialOverlay/TutorialOverlay.tsx +554 -0
  217. package/src/components/feedback/TutorialOverlay/TutorialOverlay.types.ts +30 -0
  218. package/src/components/feedback/TutorialOverlay/index.ts +2 -0
  219. package/src/components/feedback/index.ts +6 -0
  220. package/src/components/form/AddressAutocomplete/AddressAutocomplete.md +633 -0
  221. package/src/components/form/AddressAutocomplete/AddressAutocomplete.stories.tsx +663 -0
  222. package/src/components/form/AddressAutocomplete/AddressAutocomplete.test.stories.tsx +723 -0
  223. package/src/components/form/AddressAutocomplete/AddressAutocomplete.tsx +836 -0
  224. package/src/components/form/AddressAutocomplete/AddressAutocomplete.types.ts +37 -0
  225. package/src/components/form/AddressAutocomplete/index.ts +2 -0
  226. package/src/components/form/Autocomplete/Autocomplete.helpers.ts +115 -0
  227. package/src/components/form/Autocomplete/Autocomplete.keys.ts +134 -0
  228. package/src/components/form/Autocomplete/Autocomplete.parts.tsx +337 -0
  229. package/src/components/form/Autocomplete/Autocomplete.stories.tsx +715 -0
  230. package/src/components/form/Autocomplete/Autocomplete.test.stories.tsx +825 -0
  231. package/src/components/form/Autocomplete/Autocomplete.tsx +166 -0
  232. package/src/components/form/Autocomplete/Autocomplete.types.ts +116 -0
  233. package/src/components/form/Autocomplete/autocomplete.md +789 -0
  234. package/src/components/form/Autocomplete/index.ts +8 -0
  235. package/src/components/form/Autocomplete/useAutocomplete.ts +311 -0
  236. package/src/components/form/Button/Button.md +411 -0
  237. package/src/components/form/Button/Button.stories.tsx +362 -0
  238. package/src/components/form/Button/Button.test.stories.tsx +603 -0
  239. package/src/components/form/Button/Button.tsx +326 -0
  240. package/src/components/form/Button/Button.types.ts +74 -0
  241. package/src/components/form/Button/index.ts +2 -0
  242. package/src/components/form/Calendar/Calendar.md +807 -0
  243. package/src/components/form/Calendar/Calendar.stories.tsx +349 -0
  244. package/src/components/form/Calendar/Calendar.test.stories.tsx +465 -0
  245. package/src/components/form/Calendar/Calendar.tsx +571 -0
  246. package/src/components/form/Calendar/Calendar.types.ts +81 -0
  247. package/src/components/form/Calendar/index.ts +11 -0
  248. package/src/components/form/Checkbox/Checkbox.md +200 -0
  249. package/src/components/form/Checkbox/Checkbox.stories.tsx +265 -0
  250. package/src/components/form/Checkbox/Checkbox.test.stories.tsx +181 -0
  251. package/src/components/form/Checkbox/Checkbox.tsx +170 -0
  252. package/src/components/form/Checkbox/Checkbox.types.ts +20 -0
  253. package/src/components/form/Checkbox/index.ts +2 -0
  254. package/src/components/form/CodeEditor/CodeEditor.md +350 -0
  255. package/src/components/form/CodeEditor/CodeEditor.stories.tsx +871 -0
  256. package/src/components/form/CodeEditor/CodeEditor.test.stories.tsx +575 -0
  257. package/src/components/form/CodeEditor/CodeEditor.tsx +415 -0
  258. package/src/components/form/CodeEditor/CodeEditor.types.ts +38 -0
  259. package/src/components/form/CodeEditor/index.ts +2 -0
  260. package/src/components/form/Command/Command.md +468 -0
  261. package/src/components/form/Command/Command.stories.tsx +580 -0
  262. package/src/components/form/Command/Command.test.stories.tsx +215 -0
  263. package/src/components/form/Command/Command.tsx +545 -0
  264. package/src/components/form/Command/Command.types.ts +116 -0
  265. package/src/components/form/Command/index.ts +12 -0
  266. package/src/components/form/CreatableSelect/CreatableSelect.md +114 -0
  267. package/src/components/form/CreatableSelect/CreatableSelect.stories.tsx +112 -0
  268. package/src/components/form/CreatableSelect/CreatableSelect.test.stories.tsx +134 -0
  269. package/src/components/form/CreatableSelect/CreatableSelect.tsx +149 -0
  270. package/src/components/form/CreatableSelect/CreatableSelect.types.ts +37 -0
  271. package/src/components/form/CreatableSelect/index.ts +2 -0
  272. package/src/components/form/Form/Form.md +325 -0
  273. package/src/components/form/Form/Form.stories.tsx +687 -0
  274. package/src/components/form/Form/Form.test.stories.tsx +601 -0
  275. package/src/components/form/Form/Form.tsx +136 -0
  276. package/src/components/form/Form/Form.types.ts +42 -0
  277. package/src/components/form/Form/index.ts +8 -0
  278. package/src/components/form/Input/Input.md +252 -0
  279. package/src/components/form/Input/Input.stories.tsx +256 -0
  280. package/src/components/form/Input/Input.test.stories.tsx +1184 -0
  281. package/src/components/form/Input/Input.tsx +263 -0
  282. package/src/components/form/Input/Input.types.ts +24 -0
  283. package/src/components/form/Input/index.ts +2 -0
  284. package/src/components/form/InputOTP/InputOTP.md +419 -0
  285. package/src/components/form/InputOTP/InputOTP.stories.tsx +774 -0
  286. package/src/components/form/InputOTP/InputOTP.test.stories.tsx +596 -0
  287. package/src/components/form/InputOTP/InputOTP.tsx +231 -0
  288. package/src/components/form/InputOTP/InputOTP.types.ts +68 -0
  289. package/src/components/form/InputOTP/index.ts +2 -0
  290. package/src/components/form/Label/Label.md +426 -0
  291. package/src/components/form/Label/Label.stories.tsx +473 -0
  292. package/src/components/form/Label/Label.test.stories.tsx +909 -0
  293. package/src/components/form/Label/Label.tsx +367 -0
  294. package/src/components/form/Label/Label.types.ts +35 -0
  295. package/src/components/form/Label/index.ts +2 -0
  296. package/src/components/form/Menubar/Menubar.md +275 -0
  297. package/src/components/form/Menubar/Menubar.stories.tsx +472 -0
  298. package/src/components/form/Menubar/Menubar.test.stories.tsx +588 -0
  299. package/src/components/form/Menubar/Menubar.tsx +467 -0
  300. package/src/components/form/Menubar/Menubar.types.ts +71 -0
  301. package/src/components/form/Menubar/index.ts +8 -0
  302. package/src/components/form/PasswordStrength/PasswordStrength.md +139 -0
  303. package/src/components/form/PasswordStrength/PasswordStrength.stories.tsx +562 -0
  304. package/src/components/form/PasswordStrength/PasswordStrength.test.stories.tsx +327 -0
  305. package/src/components/form/PasswordStrength/PasswordStrength.tsx +419 -0
  306. package/src/components/form/PasswordStrength/PasswordStrength.types.ts +18 -0
  307. package/src/components/form/PasswordStrength/index.ts +2 -0
  308. package/src/components/form/PhoneInput/PhoneInput.md +578 -0
  309. package/src/components/form/PhoneInput/PhoneInput.stories.tsx +495 -0
  310. package/src/components/form/PhoneInput/PhoneInput.test.stories.tsx +666 -0
  311. package/src/components/form/PhoneInput/PhoneInput.tsx +376 -0
  312. package/src/components/form/PhoneInput/PhoneInput.types.ts +25 -0
  313. package/src/components/form/PhoneInput/index.ts +2 -0
  314. package/src/components/form/RadioGroup/RadioGroup.md +477 -0
  315. package/src/components/form/RadioGroup/RadioGroup.stories.tsx +518 -0
  316. package/src/components/form/RadioGroup/RadioGroup.test.stories.tsx +685 -0
  317. package/src/components/form/RadioGroup/RadioGroup.tsx +664 -0
  318. package/src/components/form/RadioGroup/RadioGroup.types.ts +82 -0
  319. package/src/components/form/RadioGroup/index.ts +2 -0
  320. package/src/components/form/RichTextEditor/RichTextEditor.md +710 -0
  321. package/src/components/form/RichTextEditor/RichTextEditor.stories.tsx +261 -0
  322. package/src/components/form/RichTextEditor/RichTextEditor.test.stories.tsx +498 -0
  323. package/src/components/form/RichTextEditor/RichTextEditor.tsx +468 -0
  324. package/src/components/form/RichTextEditor/RichTextEditor.types.ts +72 -0
  325. package/src/components/form/RichTextEditor/index.ts +2 -0
  326. package/src/components/form/SearchPalette/SearchPalette.md +69 -0
  327. package/src/components/form/SearchPalette/SearchPalette.parts.tsx +358 -0
  328. package/src/components/form/SearchPalette/SearchPalette.stories.tsx +135 -0
  329. package/src/components/form/SearchPalette/SearchPalette.tsx +141 -0
  330. package/src/components/form/SearchPalette/SearchPalette.types.ts +82 -0
  331. package/src/components/form/SearchPalette/index.ts +7 -0
  332. package/src/components/form/Select/Select.md +254 -0
  333. package/src/components/form/Select/Select.stories.tsx +364 -0
  334. package/src/components/form/Select/Select.test.stories.tsx +977 -0
  335. package/src/components/form/Select/Select.tsx +239 -0
  336. package/src/components/form/Select/Select.types.ts +57 -0
  337. package/src/components/form/Select/index.ts +2 -0
  338. package/src/components/form/Slider/Slider.md +326 -0
  339. package/src/components/form/Slider/Slider.stories.tsx +418 -0
  340. package/src/components/form/Slider/Slider.test.stories.tsx +1044 -0
  341. package/src/components/form/Slider/Slider.tsx +374 -0
  342. package/src/components/form/Slider/Slider.types.ts +113 -0
  343. package/src/components/form/Slider/index.ts +2 -0
  344. package/src/components/form/Switch/Switch.md +565 -0
  345. package/src/components/form/Switch/Switch.stories.tsx +697 -0
  346. package/src/components/form/Switch/Switch.test.stories.tsx +597 -0
  347. package/src/components/form/Switch/Switch.tsx +578 -0
  348. package/src/components/form/Switch/Switch.types.ts +130 -0
  349. package/src/components/form/Switch/index.ts +2 -0
  350. package/src/components/form/Textarea/Textarea.stories.tsx +473 -0
  351. package/src/components/form/Textarea/Textarea.test.stories.tsx +708 -0
  352. package/src/components/form/Textarea/Textarea.tsx +678 -0
  353. package/src/components/form/Textarea/Textarea.types.ts +84 -0
  354. package/src/components/form/Textarea/index.ts +2 -0
  355. package/src/components/form/Toggle/Toggle.md +234 -0
  356. package/src/components/form/Toggle/Toggle.stories.tsx +638 -0
  357. package/src/components/form/Toggle/Toggle.test.stories.tsx +1167 -0
  358. package/src/components/form/Toggle/Toggle.tsx +265 -0
  359. package/src/components/form/Toggle/Toggle.types.ts +79 -0
  360. package/src/components/form/Toggle/index.ts +2 -0
  361. package/src/components/form/ToggleGroup/ToggleGroup.md +329 -0
  362. package/src/components/form/ToggleGroup/ToggleGroup.stories.tsx +617 -0
  363. package/src/components/form/ToggleGroup/ToggleGroup.test.stories.tsx +918 -0
  364. package/src/components/form/ToggleGroup/ToggleGroup.tsx +129 -0
  365. package/src/components/form/ToggleGroup/ToggleGroup.types.ts +53 -0
  366. package/src/components/form/ToggleGroup/index.ts +2 -0
  367. package/src/components/form/UploadButton/UploadButton.md +44 -0
  368. package/src/components/form/UploadButton/UploadButton.stories.tsx +366 -0
  369. package/src/components/form/UploadButton/UploadButton.test.stories.tsx +454 -0
  370. package/src/components/form/UploadButton/UploadButton.tsx +312 -0
  371. package/src/components/form/UploadButton/UploadButton.types.ts +58 -0
  372. package/src/components/form/UploadButton/index.ts +2 -0
  373. package/src/components/form/index.ts +25 -0
  374. package/src/components/form/total-form/Fields/SelectField.tsx +57 -0
  375. package/src/components/form/total-form/Fields/TextField.tsx +58 -0
  376. package/src/components/form/total-form/Fields/index.ts +4 -0
  377. package/src/components/form/total-form/FormContainer.tsx +104 -0
  378. package/src/components/form/total-form/FormContext.tsx +38 -0
  379. package/src/components/form/total-form/FormErrorSnackbar.tsx +35 -0
  380. package/src/components/form/total-form/SubmitButton.tsx +27 -0
  381. package/src/components/form/total-form/index.ts +12 -0
  382. package/src/components/form/total-form/total-form.test.tsx +97 -0
  383. package/src/components/index.ts +7 -0
  384. package/src/components/layout/Accordion/Accordion.md +725 -0
  385. package/src/components/layout/Accordion/Accordion.stories.tsx +690 -0
  386. package/src/components/layout/Accordion/Accordion.test.stories.tsx +1362 -0
  387. package/src/components/layout/Accordion/Accordion.tsx +242 -0
  388. package/src/components/layout/Accordion/Accordion.types.ts +32 -0
  389. package/src/components/layout/Accordion/index.ts +8 -0
  390. package/src/components/layout/Card/Card.md +533 -0
  391. package/src/components/layout/Card/Card.stories.tsx +593 -0
  392. package/src/components/layout/Card/Card.test.stories.tsx +1134 -0
  393. package/src/components/layout/Card/Card.tsx +404 -0
  394. package/src/components/layout/Card/Card.types.ts +57 -0
  395. package/src/components/layout/Card/index.ts +8 -0
  396. package/src/components/layout/Collapsible/Collapsible.md +135 -0
  397. package/src/components/layout/Collapsible/Collapsible.stories.tsx +180 -0
  398. package/src/components/layout/Collapsible/Collapsible.test.stories.tsx +304 -0
  399. package/src/components/layout/Collapsible/Collapsible.tsx +198 -0
  400. package/src/components/layout/Collapsible/Collapsible.types.ts +35 -0
  401. package/src/components/layout/Collapsible/index.ts +6 -0
  402. package/src/components/layout/Container/Container.md +420 -0
  403. package/src/components/layout/Container/Container.stories.tsx +557 -0
  404. package/src/components/layout/Container/Container.test.stories.tsx +750 -0
  405. package/src/components/layout/Container/Container.tsx +72 -0
  406. package/src/components/layout/Container/Container.types.ts +11 -0
  407. package/src/components/layout/Container/index.ts +2 -0
  408. package/src/components/layout/ContentToolbar/ColumnsMenu.tsx +99 -0
  409. package/src/components/layout/ContentToolbar/ContentToolbar.md +75 -0
  410. package/src/components/layout/ContentToolbar/ContentToolbar.stories.tsx +129 -0
  411. package/src/components/layout/ContentToolbar/ContentToolbar.test.stories.tsx +251 -0
  412. package/src/components/layout/ContentToolbar/ContentToolbar.tsx +108 -0
  413. package/src/components/layout/ContentToolbar/ContentToolbar.types.ts +229 -0
  414. package/src/components/layout/ContentToolbar/FilterTrigger.tsx +71 -0
  415. package/src/components/layout/ContentToolbar/MultiSelectDropdown.tsx +297 -0
  416. package/src/components/layout/ContentToolbar/SavedViewsMenu.tsx +334 -0
  417. package/src/components/layout/ContentToolbar/SortByDropdown.tsx +213 -0
  418. package/src/components/layout/ContentToolbar/ViewSelector.tsx +98 -0
  419. package/src/components/layout/ContentToolbar/__tests__/ColumnsMenu.test.tsx +39 -0
  420. package/src/components/layout/ContentToolbar/__tests__/MultiSelectDropdown.test.tsx +110 -0
  421. package/src/components/layout/ContentToolbar/__tests__/SavedViewsMenu.test.tsx +99 -0
  422. package/src/components/layout/ContentToolbar/index.ts +24 -0
  423. package/src/components/layout/ContentToolbar/tests.md +42 -0
  424. package/src/components/layout/ContentToolbar/track.md +41 -0
  425. package/src/components/layout/Dashboard/Dashboard.md +71 -0
  426. package/src/components/layout/Dashboard/Dashboard.stories.tsx +104 -0
  427. package/src/components/layout/Dashboard/Dashboard.test.stories.tsx +164 -0
  428. package/src/components/layout/Dashboard/Dashboard.tsx +297 -0
  429. package/src/components/layout/Dashboard/Dashboard.types.ts +157 -0
  430. package/src/components/layout/Dashboard/DashboardContext.tsx +47 -0
  431. package/src/components/layout/Dashboard/DashboardParts.tsx +216 -0
  432. package/src/components/layout/Dashboard/index.ts +18 -0
  433. package/src/components/layout/Dashboard/tests.md +46 -0
  434. package/src/components/layout/Dashboard/track.md +50 -0
  435. package/src/components/layout/Drawer/Drawer.md +479 -0
  436. package/src/components/layout/Drawer/Drawer.stories.tsx +660 -0
  437. package/src/components/layout/Drawer/Drawer.test.stories.tsx +1339 -0
  438. package/src/components/layout/Drawer/Drawer.tsx +150 -0
  439. package/src/components/layout/Drawer/Drawer.types.ts +34 -0
  440. package/src/components/layout/Drawer/index.ts +2 -0
  441. package/src/components/layout/Resizable/Resizable.md +308 -0
  442. package/src/components/layout/Resizable/Resizable.stories.tsx +1039 -0
  443. package/src/components/layout/Resizable/Resizable.test.stories.tsx +750 -0
  444. package/src/components/layout/Resizable/Resizable.tsx +190 -0
  445. package/src/components/layout/Resizable/Resizable.types.ts +34 -0
  446. package/src/components/layout/Resizable/index.ts +2 -0
  447. package/src/components/layout/ScrollArea/ScrollArea.md +122 -0
  448. package/src/components/layout/ScrollArea/ScrollArea.stories.tsx +651 -0
  449. package/src/components/layout/ScrollArea/ScrollArea.test.stories.tsx +619 -0
  450. package/src/components/layout/ScrollArea/ScrollArea.tsx +449 -0
  451. package/src/components/layout/ScrollArea/ScrollArea.types.ts +80 -0
  452. package/src/components/layout/ScrollArea/index.ts +7 -0
  453. package/src/components/layout/Separator/Separator.stories.tsx +563 -0
  454. package/src/components/layout/Separator/Separator.test.stories.tsx +527 -0
  455. package/src/components/layout/Separator/Separator.tsx +187 -0
  456. package/src/components/layout/Separator/Separator.types.ts +17 -0
  457. package/src/components/layout/Separator/index.ts +2 -0
  458. package/src/components/layout/SettingsLayout/SettingsLayout.md +139 -0
  459. package/src/components/layout/SettingsLayout/SettingsLayout.parts.tsx +357 -0
  460. package/src/components/layout/SettingsLayout/SettingsLayout.stories.tsx +194 -0
  461. package/src/components/layout/SettingsLayout/SettingsLayout.test.stories.tsx +175 -0
  462. package/src/components/layout/SettingsLayout/SettingsLayout.tsx +69 -0
  463. package/src/components/layout/SettingsLayout/SettingsLayout.types.ts +61 -0
  464. package/src/components/layout/SettingsLayout/index.ts +6 -0
  465. package/src/components/layout/Sidebar/Sidebar.md +367 -0
  466. package/src/components/layout/Sidebar/Sidebar.stories.tsx +611 -0
  467. package/src/components/layout/Sidebar/Sidebar.test.stories.tsx +1326 -0
  468. package/src/components/layout/Sidebar/Sidebar.tsx +131 -0
  469. package/src/components/layout/Sidebar/Sidebar.types.ts +30 -0
  470. package/src/components/layout/Sidebar/index.ts +7 -0
  471. package/src/components/layout/Skeleton/Skeleton.md +240 -0
  472. package/src/components/layout/Skeleton/Skeleton.stories.tsx +689 -0
  473. package/src/components/layout/Skeleton/Skeleton.test.stories.tsx +521 -0
  474. package/src/components/layout/Skeleton/Skeleton.tsx +166 -0
  475. package/src/components/layout/Skeleton/Skeleton.types.ts +19 -0
  476. package/src/components/layout/Skeleton/index.ts +2 -0
  477. package/src/components/layout/Spacer/Spacer.md +84 -0
  478. package/src/components/layout/Spacer/Spacer.stories.tsx +502 -0
  479. package/src/components/layout/Spacer/Spacer.test.stories.tsx +472 -0
  480. package/src/components/layout/Spacer/Spacer.tsx +68 -0
  481. package/src/components/layout/Spacer/Spacer.types.ts +12 -0
  482. package/src/components/layout/Spacer/index.ts +2 -0
  483. package/src/components/layout/TableFilter/TableFilter.md +55 -0
  484. package/src/components/layout/TableFilter/TableFilter.stories.tsx +82 -0
  485. package/src/components/layout/TableFilter/TableFilter.test.stories.tsx +87 -0
  486. package/src/components/layout/TableFilter/TableFilter.tsx +383 -0
  487. package/src/components/layout/TableFilter/TableFilter.types.ts +87 -0
  488. package/src/components/layout/TableFilter/TableFilterContext.tsx +29 -0
  489. package/src/components/layout/TableFilter/index.ts +15 -0
  490. package/src/components/layout/TableFilter/tests.md +37 -0
  491. package/src/components/layout/TableFilter/track.md +36 -0
  492. package/src/components/layout/index.ts +14 -0
  493. package/src/components/navigation/Breadcrumbs/Breadcrumbs.md +558 -0
  494. package/src/components/navigation/Breadcrumbs/Breadcrumbs.stories.tsx +640 -0
  495. package/src/components/navigation/Breadcrumbs/Breadcrumbs.test.stories.tsx +1007 -0
  496. package/src/components/navigation/Breadcrumbs/Breadcrumbs.tsx +516 -0
  497. package/src/components/navigation/Breadcrumbs/Breadcrumbs.types.ts +132 -0
  498. package/src/components/navigation/Breadcrumbs/index.ts +2 -0
  499. package/src/components/navigation/CommandPalette/CommandPalette.md +201 -0
  500. package/src/components/navigation/CommandPalette/CommandPalette.stories.tsx +384 -0
  501. package/src/components/navigation/CommandPalette/CommandPalette.test.stories.tsx +437 -0
  502. package/src/components/navigation/CommandPalette/CommandPalette.tsx +434 -0
  503. package/src/components/navigation/CommandPalette/CommandPalette.types.ts +25 -0
  504. package/src/components/navigation/CommandPalette/index.ts +2 -0
  505. package/src/components/navigation/ContextMenu/ContextMenu.md +535 -0
  506. package/src/components/navigation/ContextMenu/ContextMenu.stories.tsx +611 -0
  507. package/src/components/navigation/ContextMenu/ContextMenu.test.stories.tsx +850 -0
  508. package/src/components/navigation/ContextMenu/ContextMenu.tsx +254 -0
  509. package/src/components/navigation/ContextMenu/ContextMenu.types.ts +96 -0
  510. package/src/components/navigation/ContextMenu/index.ts +2 -0
  511. package/src/components/navigation/DropdownMenu/DropdownMenu.md +514 -0
  512. package/src/components/navigation/DropdownMenu/DropdownMenu.stories.tsx +580 -0
  513. package/src/components/navigation/DropdownMenu/DropdownMenu.test.stories.tsx +660 -0
  514. package/src/components/navigation/DropdownMenu/DropdownMenu.tsx +305 -0
  515. package/src/components/navigation/DropdownMenu/DropdownMenu.types.ts +116 -0
  516. package/src/components/navigation/DropdownMenu/index.ts +2 -0
  517. package/src/components/navigation/NavigationMenu/NavigationMenu.md +580 -0
  518. package/src/components/navigation/NavigationMenu/NavigationMenu.tsx +874 -0
  519. package/src/components/navigation/NavigationMenu/NavigationMenu.types.ts +135 -0
  520. package/src/components/navigation/NavigationMenu/index.ts +2 -0
  521. package/src/components/navigation/NavigationMenu/stories/NavigationMenu.stories.tsx +518 -0
  522. package/src/components/navigation/NavigationMenu/stories/NavigationMenu.test.stories.tsx +931 -0
  523. package/src/components/navigation/NavigationMenu/stories/NavigationMenuHorizontal.stories.tsx +503 -0
  524. package/src/components/navigation/NavigationMenu/stories/NavigationMenuVertical.stories.tsx +455 -0
  525. package/src/components/navigation/Pagination/Pagination.md +699 -0
  526. package/src/components/navigation/Pagination/Pagination.stories.tsx +604 -0
  527. package/src/components/navigation/Pagination/Pagination.test.stories.tsx +520 -0
  528. package/src/components/navigation/Pagination/Pagination.tsx +356 -0
  529. package/src/components/navigation/Pagination/Pagination.types.ts +129 -0
  530. package/src/components/navigation/Pagination/index.ts +2 -0
  531. package/src/components/navigation/Tabs/Tabs.md +774 -0
  532. package/src/components/navigation/Tabs/Tabs.stories.tsx +1006 -0
  533. package/src/components/navigation/Tabs/Tabs.test.stories.tsx +1225 -0
  534. package/src/components/navigation/Tabs/Tabs.tsx +433 -0
  535. package/src/components/navigation/Tabs/Tabs.types.ts +239 -0
  536. package/src/components/navigation/Tabs/index.ts +2 -0
  537. package/src/components/navigation/index.ts +7 -0
  538. package/src/components/typography/Blockquote/Blockquote.md +130 -0
  539. package/src/components/typography/Blockquote/Blockquote.stories.tsx +359 -0
  540. package/src/components/typography/Blockquote/Blockquote.test.stories.tsx +432 -0
  541. package/src/components/typography/Blockquote/Blockquote.tsx +166 -0
  542. package/src/components/typography/Blockquote/Blockquote.types.ts +11 -0
  543. package/src/components/typography/Blockquote/index.ts +2 -0
  544. package/src/components/typography/Code/Code.md +182 -0
  545. package/src/components/typography/Code/Code.stories.tsx +686 -0
  546. package/src/components/typography/Code/Code.test.stories.tsx +703 -0
  547. package/src/components/typography/Code/Code.tsx +228 -0
  548. package/src/components/typography/Code/Code.types.ts +12 -0
  549. package/src/components/typography/Code/index.ts +2 -0
  550. package/src/components/typography/Heading/Heading.md +143 -0
  551. package/src/components/typography/Heading/Heading.stories.tsx +451 -0
  552. package/src/components/typography/Heading/Heading.test.stories.tsx +830 -0
  553. package/src/components/typography/Heading/Heading.tsx +178 -0
  554. package/src/components/typography/Heading/Heading.types.ts +11 -0
  555. package/src/components/typography/Heading/index.ts +2 -0
  556. package/src/components/typography/Paragraph/Paragraph.md +80 -0
  557. package/src/components/typography/Paragraph/Paragraph.stories.tsx +280 -0
  558. package/src/components/typography/Paragraph/Paragraph.test.stories.tsx +238 -0
  559. package/src/components/typography/Paragraph/Paragraph.tsx +99 -0
  560. package/src/components/typography/Paragraph/Paragraph.types.ts +10 -0
  561. package/src/components/typography/Paragraph/index.ts +2 -0
  562. package/src/components/typography/Text/Text.md +129 -0
  563. package/src/components/typography/Text/Text.stories.tsx +359 -0
  564. package/src/components/typography/Text/Text.test.stories.tsx +762 -0
  565. package/src/components/typography/Text/Text.tsx +159 -0
  566. package/src/components/typography/Text/Text.types.ts +15 -0
  567. package/src/components/typography/Text/index.ts +2 -0
  568. package/src/components/typography/index.ts +5 -0
  569. package/src/components/utility/AnimatedIcon/AnimatedIcon.md +359 -0
  570. package/src/components/utility/AnimatedIcon/AnimatedIcon.stories.tsx +947 -0
  571. package/src/components/utility/AnimatedIcon/AnimatedIcon.test.stories.tsx +596 -0
  572. package/src/components/utility/AnimatedIcon/AnimatedIcon.tsx +595 -0
  573. package/src/components/utility/AnimatedIcon/AnimatedIcon.types.ts +98 -0
  574. package/src/components/utility/AnimatedIcon/index.ts +2 -0
  575. package/src/components/utility/AspectRatio/AspectRatio.md +200 -0
  576. package/src/components/utility/AspectRatio/AspectRatio.stories.tsx +414 -0
  577. package/src/components/utility/AspectRatio/AspectRatio.test.stories.tsx +859 -0
  578. package/src/components/utility/AspectRatio/AspectRatio.tsx +76 -0
  579. package/src/components/utility/AspectRatio/AspectRatio.types.ts +13 -0
  580. package/src/components/utility/AspectRatio/index.ts +2 -0
  581. package/src/components/utility/InfiniteScroll/InfiniteScroll.md +531 -0
  582. package/src/components/utility/InfiniteScroll/InfiniteScroll.stories.tsx +620 -0
  583. package/src/components/utility/InfiniteScroll/InfiniteScroll.test.stories.tsx +358 -0
  584. package/src/components/utility/InfiniteScroll/InfiniteScroll.tsx +204 -0
  585. package/src/components/utility/InfiniteScroll/InfiniteScroll.types.ts +39 -0
  586. package/src/components/utility/InfiniteScroll/index.ts +6 -0
  587. package/src/components/utility/Portal/Portal.button-container.example.tsx +99 -0
  588. package/src/components/utility/Portal/Portal.md +593 -0
  589. package/src/components/utility/Portal/Portal.stories.tsx +340 -0
  590. package/src/components/utility/Portal/Portal.test.stories.tsx +2086 -0
  591. package/src/components/utility/Portal/Portal.tsx +39 -0
  592. package/src/components/utility/Portal/Portal.types.ts +7 -0
  593. package/src/components/utility/Portal/index.ts +2 -0
  594. package/src/components/utility/Transition/Transition.md +684 -0
  595. package/src/components/utility/Transition/Transition.stories.tsx +493 -0
  596. package/src/components/utility/Transition/Transition.test.stories.tsx +854 -0
  597. package/src/components/utility/Transition/Transition.tsx +140 -0
  598. package/src/components/utility/Transition/Transition.types.ts +14 -0
  599. package/src/components/utility/Transition/index.ts +6 -0
  600. package/src/components/utility/VirtualList/VirtualList.md +520 -0
  601. package/src/components/utility/VirtualList/VirtualList.stories.tsx +1073 -0
  602. package/src/components/utility/VirtualList/VirtualList.test.stories.tsx +1074 -0
  603. package/src/components/utility/VirtualList/VirtualList.tsx +369 -0
  604. package/src/components/utility/VirtualList/VirtualList.types.ts +56 -0
  605. package/src/components/utility/VirtualList/index.ts +7 -0
  606. package/src/components/utility/WorkflowStep/WorkflowStep.md +187 -0
  607. package/src/components/utility/WorkflowStep/WorkflowStep.stories.tsx +433 -0
  608. package/src/components/utility/WorkflowStep/WorkflowStep.test.stories.tsx +364 -0
  609. package/src/components/utility/WorkflowStep/WorkflowStep.tsx +506 -0
  610. package/src/components/utility/WorkflowStep/WorkflowStep.types.ts +133 -0
  611. package/src/components/utility/WorkflowStep/index.ts +13 -0
  612. package/src/components/utility/index.ts +7 -0
  613. package/src/index.ts +17 -0
  614. package/src/mui/AppBar.ts +2 -0
  615. package/src/mui/Box.ts +2 -0
  616. package/src/mui/CssBaseline.ts +2 -0
  617. package/src/mui/FormControl.ts +2 -0
  618. package/src/mui/FormControlLabel.ts +2 -0
  619. package/src/mui/Grid2.ts +2 -0
  620. package/src/mui/InputLabel.ts +2 -0
  621. package/src/mui/List.ts +2 -0
  622. package/src/mui/ListItem.ts +2 -0
  623. package/src/mui/ListItemButton.ts +2 -0
  624. package/src/mui/ListItemText.ts +2 -0
  625. package/src/mui/Stack.ts +2 -0
  626. package/src/mui/SvgIcon.ts +2 -0
  627. package/src/mui/Toolbar.ts +2 -0
  628. package/src/mui/styles.ts +2 -0
  629. package/src/mui/useMediaQuery.ts +1 -0
  630. package/src/social-login-button.tsx +199 -0
  631. package/src/user-avatar.tsx +102 -0
  632. package/src/utils/cn.ts +9 -0
  633. package/src/utils/index.ts +1 -0
@@ -0,0 +1,1225 @@
1
+ import {
2
+ Dashboard,
3
+ Email,
4
+ Home,
5
+ Notifications,
6
+ Person,
7
+ Security,
8
+ Settings,
9
+ } from '@mui/icons-material';
10
+ import { Box, Typography } from '@mui/material';
11
+ import type { Meta, StoryObj } from '@storybook/react-vite';
12
+ import { useState } from 'react';
13
+ import { expect, fn,userEvent, waitFor, within } from 'storybook/test';
14
+
15
+ import { Tabs } from './Tabs';
16
+ import type { TabItem, TabsProps } from './Tabs.types';
17
+
18
+ const meta: Meta<typeof Tabs> = {
19
+ title: 'Navigation/Tabs/Tests',
20
+ component: Tabs,
21
+ parameters: {
22
+ layout: 'centered',
23
+ chromatic: { disableSnapshot: false },
24
+ },
25
+ tags: ['autodocs', 'test', 'component:Tabs'],
26
+ };
27
+
28
+ export default meta;
29
+ type Story = StoryObj<typeof meta>;
30
+
31
+ // Test wrapper component
32
+ interface TabsTestWrapperProps extends Partial<TabsProps> {
33
+ onChangeCallback?: typeof fn;
34
+ onTabCloseCallback?: typeof fn;
35
+ onFocusCallback?: typeof fn;
36
+ onBlurCallback?: typeof fn;
37
+ initialValue?: string;
38
+ }
39
+
40
+ const TabsTestWrapper = ({
41
+ onChangeCallback = fn(),
42
+ onTabCloseCallback = fn(),
43
+ onFocusCallback = fn(),
44
+ onBlurCallback = fn(),
45
+ initialValue = 'tab1',
46
+ ...props
47
+ }: TabsTestWrapperProps) => {
48
+ const [value, setValue] = useState(initialValue);
49
+
50
+ const handleChange = (event: React.SyntheticEvent, tabId: string) => {
51
+ setValue(tabId);
52
+ onChangeCallback(event, tabId);
53
+ };
54
+
55
+ const handleTabClose = (tabId: string) => {
56
+ onTabCloseCallback(tabId);
57
+ };
58
+
59
+ return (
60
+ <Box sx={{ width: 600, minHeight: 300 }}>
61
+ <Tabs
62
+ {...props}
63
+ value={value}
64
+ onChange={handleChange}
65
+ onTabClose={handleTabClose}
66
+ onFocus={onFocusCallback}
67
+ onBlur={onBlurCallback}
68
+ />
69
+ </Box>
70
+ );
71
+ };
72
+
73
+ // Basic tab items for testing
74
+ const basicTestItems: TabItem[] = [
75
+ {
76
+ id: 'tab1',
77
+ label: 'Tab 1',
78
+ content: (
79
+ <Box sx={{ p: 2 }}>
80
+ <Typography>Content for Tab 1</Typography>
81
+ </Box>
82
+ ),
83
+ },
84
+ {
85
+ id: 'tab2',
86
+ label: 'Tab 2',
87
+ content: (
88
+ <Box sx={{ p: 2 }}>
89
+ <Typography>Content for Tab 2</Typography>
90
+ </Box>
91
+ ),
92
+ },
93
+ {
94
+ id: 'tab3',
95
+ label: 'Tab 3',
96
+ content: (
97
+ <Box sx={{ p: 2 }}>
98
+ <Typography>Content for Tab 3</Typography>
99
+ </Box>
100
+ ),
101
+ },
102
+ ];
103
+
104
+ const itemsWithIcons: TabItem[] = [
105
+ {
106
+ id: 'home',
107
+ label: 'Home',
108
+ icon: <Home />,
109
+ content: (
110
+ <Box sx={{ p: 2 }}>
111
+ <Typography>Home content</Typography>
112
+ </Box>
113
+ ),
114
+ },
115
+ {
116
+ id: 'settings',
117
+ label: 'Settings',
118
+ icon: <Settings />,
119
+ content: (
120
+ <Box sx={{ p: 2 }}>
121
+ <Typography>Settings content</Typography>
122
+ </Box>
123
+ ),
124
+ },
125
+ {
126
+ id: 'profile',
127
+ label: 'Profile',
128
+ icon: <Person />,
129
+ content: (
130
+ <Box sx={{ p: 2 }}>
131
+ <Typography>Profile content</Typography>
132
+ </Box>
133
+ ),
134
+ },
135
+ ];
136
+
137
+ // 1. Basic Interaction Test
138
+ export const BasicInteraction: Story = {
139
+ name: '🧪 Basic Interaction Test',
140
+ args: {
141
+ items: basicTestItems,
142
+ onChangeCallback: fn(),
143
+ onTabCloseCallback: fn(),
144
+ onFocusCallback: fn(),
145
+ onBlurCallback: fn(),
146
+ },
147
+ render: (args) => <TabsTestWrapper {...args} />,
148
+ parameters: {
149
+ test: {
150
+ dangerouslyIgnoreUnhandledErrors: true,
151
+ },
152
+ },
153
+ play: async ({ canvasElement, step }) => {
154
+ const canvas = within(canvasElement);
155
+
156
+ await step('Initial render verification', async () => {
157
+ // Check tabs are rendered
158
+ const tab1 = canvas.getByRole('tab', { name: /Tab 1/i });
159
+ const tab2 = canvas.getByRole('tab', { name: /Tab 2/i });
160
+ const tab3 = canvas.getByRole('tab', { name: /Tab 3/i });
161
+
162
+ await expect(tab1).toBeInTheDocument();
163
+ await expect(tab2).toBeInTheDocument();
164
+ await expect(tab3).toBeInTheDocument();
165
+
166
+ // Check first tab is selected
167
+ await expect(tab1).toHaveAttribute('aria-selected', 'true');
168
+ await expect(tab2).toHaveAttribute('aria-selected', 'false');
169
+
170
+ // Check first panel is visible
171
+ const panel1 = canvas.getByRole('tabpanel', { name: /Tab 1/i });
172
+ await expect(panel1).toBeInTheDocument();
173
+ await expect(panel1).toHaveTextContent('Content for Tab 1');
174
+ });
175
+
176
+ await step('Tab click interaction', async () => {
177
+ const tab2 = canvas.getByRole('tab', { name: /Tab 2/i });
178
+ await userEvent.click(tab2);
179
+
180
+ // Check tab2 is now selected
181
+ await expect(tab2).toHaveAttribute('aria-selected', 'true');
182
+
183
+ // Check panel2 is now visible
184
+ const panel2 = canvas.getByRole('tabpanel', { name: /Tab 2/i });
185
+ await expect(panel2).toBeInTheDocument();
186
+ await expect(panel2).toHaveTextContent('Content for Tab 2');
187
+ });
188
+
189
+ await step('Tab click on already selected tab', async () => {
190
+ const tab2 = canvas.getByRole('tab', { name: /Tab 2/i });
191
+ await userEvent.click(tab2);
192
+
193
+ // Should still be selected
194
+ await expect(tab2).toHaveAttribute('aria-selected', 'true');
195
+ });
196
+ },
197
+ };
198
+
199
+ // 2. Keyboard Navigation Test
200
+ export const KeyboardNavigation: Story = {
201
+ name: '⌨️ Keyboard Navigation Test',
202
+ args: {
203
+ items: basicTestItems,
204
+ onChangeCallback: fn(),
205
+ onTabCloseCallback: fn(),
206
+ onFocusCallback: fn(),
207
+ onBlurCallback: fn(),
208
+ },
209
+ render: (args) => <TabsTestWrapper {...args} />,
210
+ parameters: {
211
+ a11y: {
212
+ element: '#storybook-root',
213
+ config: {
214
+ rules: [
215
+ { id: 'color-contrast', enabled: true },
216
+ { id: 'aria-required-attr', enabled: true },
217
+ { id: 'aria-roles', enabled: true },
218
+ { id: 'aria-valid-attr-value', enabled: true },
219
+ ],
220
+ },
221
+ },
222
+ },
223
+ play: async ({ canvasElement, step }) => {
224
+ const canvas = within(canvasElement);
225
+
226
+ await step('Tab navigation with arrow keys', async () => {
227
+ const tab1 = canvas.getByRole('tab', { name: /Tab 1/i });
228
+ const tab2 = canvas.getByRole('tab', { name: /Tab 2/i });
229
+ const tab3 = canvas.getByRole('tab', { name: /Tab 3/i });
230
+
231
+ // Focus first tab
232
+ tab1.focus();
233
+ await expect(tab1).toHaveFocus();
234
+
235
+ // Navigate right with arrow key
236
+ await userEvent.keyboard('{ArrowRight}');
237
+ await expect(tab2).toHaveFocus();
238
+
239
+ // Navigate right again
240
+ await userEvent.keyboard('{ArrowRight}');
241
+ await expect(tab3).toHaveFocus();
242
+
243
+ // Navigate left
244
+ await userEvent.keyboard('{ArrowLeft}');
245
+ await expect(tab2).toHaveFocus();
246
+ });
247
+
248
+ await step('Tab activation with Enter key', async () => {
249
+ const tab3 = canvas.getByRole('tab', { name: /Tab 3/i });
250
+
251
+ // Focus tab3
252
+ tab3.focus();
253
+ await expect(tab3).toHaveFocus();
254
+
255
+ // Activate with Enter
256
+ await userEvent.keyboard('{Enter}');
257
+
258
+ // Check tab3 is selected
259
+ await expect(tab3).toHaveAttribute('aria-selected', 'true');
260
+
261
+ // Check panel3 is visible
262
+ const panel3 = canvas.getByRole('tabpanel', { name: /Tab 3/i });
263
+ await expect(panel3).toBeInTheDocument();
264
+ await expect(panel3).toHaveTextContent('Content for Tab 3');
265
+ });
266
+
267
+ await step('Tab navigation with Tab key', async () => {
268
+ const tab1 = canvas.getByRole('tab', { name: /Tab 1/i });
269
+
270
+ // Focus first tab
271
+ tab1.focus();
272
+ await expect(tab1).toHaveFocus();
273
+
274
+ // Tab to content
275
+ await userEvent.tab();
276
+
277
+ // Should have moved focus out of tabs
278
+ await expect(tab1).not.toHaveFocus();
279
+ });
280
+ },
281
+ };
282
+
283
+ // 3. Closable Tabs Test
284
+ export const ClosableTabsTest: Story = {
285
+ name: '❌ Closable Tabs Test',
286
+ args: {
287
+ onChange: fn(),
288
+ onTabClose: fn(),
289
+ onFocus: fn(),
290
+ onBlur: fn(),
291
+ items: [
292
+ {
293
+ id: 'tab1',
294
+ label: 'Tab 1',
295
+ closable: true,
296
+ content: (
297
+ <Box sx={{ p: 2 }}>
298
+ <Typography>Content 1</Typography>
299
+ </Box>
300
+ ),
301
+ },
302
+ {
303
+ id: 'tab2',
304
+ label: 'Tab 2',
305
+ closable: true,
306
+ content: (
307
+ <Box sx={{ p: 2 }}>
308
+ <Typography>Content 2</Typography>
309
+ </Box>
310
+ ),
311
+ },
312
+ {
313
+ id: 'tab3',
314
+ label: 'Tab 3',
315
+ closable: false,
316
+ content: (
317
+ <Box sx={{ p: 2 }}>
318
+ <Typography>Content 3</Typography>
319
+ </Box>
320
+ ),
321
+ },
322
+ ],
323
+ },
324
+ render: (args) => {
325
+ const ClosableTabsWrapper = () => {
326
+ const [tabs, setTabs] = useState(args.items);
327
+ const [value, setValue] = useState('tab1');
328
+
329
+ const handleChange = (event: React.SyntheticEvent, tabId: string) => {
330
+ setValue(tabId);
331
+ args.onChange(event, tabId);
332
+ };
333
+
334
+ const handleTabClose = (tabId: string) => {
335
+ const newTabs = tabs.filter((tab) => tab.id !== tabId);
336
+ setTabs(newTabs);
337
+ if (value === tabId && newTabs.length > 0) {
338
+ setValue(newTabs[0].id);
339
+ }
340
+ args.onTabClose(tabId);
341
+ };
342
+
343
+ return (
344
+ <Box sx={{ width: 600, minHeight: 300 }}>
345
+ <Tabs
346
+ {...args}
347
+ items={tabs}
348
+ value={value}
349
+ onChange={handleChange}
350
+ onTabClose={handleTabClose}
351
+ onFocus={args.onFocus}
352
+ onBlur={args.onBlur}
353
+ />
354
+ </Box>
355
+ );
356
+ };
357
+
358
+ return <ClosableTabsWrapper />;
359
+ },
360
+ play: async ({ canvasElement, step }) => {
361
+ const canvas = within(canvasElement);
362
+
363
+ await step('Verify close buttons are rendered', async () => {
364
+ // Check close buttons for closable tabs
365
+ const closeButtons = canvas.getAllByRole('button', { name: 'Close tab' });
366
+ // Should have 2 close buttons (tab1 and tab2)
367
+ await expect(closeButtons).toHaveLength(2);
368
+ });
369
+
370
+ await step('Close a tab', async () => {
371
+ // Get the first close button
372
+ const closeButtons = canvas.getAllByRole('button', { name: 'Close tab' });
373
+ const firstCloseButton = closeButtons[0];
374
+
375
+ // Click close button
376
+ await userEvent.click(firstCloseButton);
377
+
378
+ // Wait for tab to be removed
379
+ await waitFor(() => {
380
+ const tabs = canvas.getAllByRole('tab');
381
+ expect(tabs).toHaveLength(2);
382
+ });
383
+ });
384
+
385
+ await step('Verify non-closable tab has no close button', async () => {
386
+ const tab3 = canvas.getByRole('tab', { name: /Tab 3/i });
387
+
388
+ // Should not have a close button within Tab 3
389
+ const closeButtonInTab3 = within(tab3).queryByRole('button', { name: 'Close tab' });
390
+ await expect(closeButtonInTab3).not.toBeInTheDocument();
391
+ });
392
+ },
393
+ };
394
+
395
+ // 4. Badge Test
396
+ export const BadgeTest: Story = {
397
+ name: '🔴 Badge Test',
398
+ args: {
399
+ items: [
400
+ {
401
+ id: 'messages',
402
+ label: 'Messages',
403
+ icon: <Email />,
404
+ badge: 5,
405
+ content: (
406
+ <Box sx={{ p: 2 }}>
407
+ <Typography>5 new messages</Typography>
408
+ </Box>
409
+ ),
410
+ },
411
+ {
412
+ id: 'notifications',
413
+ label: 'Notifications',
414
+ icon: <Notifications />,
415
+ badge: 99,
416
+ content: (
417
+ <Box sx={{ p: 2 }}>
418
+ <Typography>99+ notifications</Typography>
419
+ </Box>
420
+ ),
421
+ },
422
+ {
423
+ id: 'dashboard',
424
+ label: 'Dashboard',
425
+ icon: <Dashboard />,
426
+ content: (
427
+ <Box sx={{ p: 2 }}>
428
+ <Typography>Dashboard content</Typography>
429
+ </Box>
430
+ ),
431
+ },
432
+ ],
433
+ onChangeCallback: fn(),
434
+ onTabCloseCallback: fn(),
435
+ onFocusCallback: fn(),
436
+ onBlurCallback: fn(),
437
+ },
438
+ render: (args) => <TabsTestWrapper {...args} initialValue="messages" />,
439
+ play: async ({ canvasElement, step }) => {
440
+ const canvas = within(canvasElement);
441
+
442
+ await step('Verify badges are rendered', async () => {
443
+ // Check for badge elements
444
+ const badges = canvas.getAllByText(/^(5|99)$/);
445
+ await expect(badges).toHaveLength(2);
446
+
447
+ // Verify badge content
448
+ await expect(canvas.getByText('5')).toBeInTheDocument();
449
+ await expect(canvas.getByText('99')).toBeInTheDocument();
450
+ });
451
+
452
+ await step('Verify tab without badge', async () => {
453
+ const dashboardTab = canvas.getByRole('tab', { name: /Dashboard/i });
454
+ await expect(dashboardTab).toBeInTheDocument();
455
+
456
+ // Dashboard tab should not contain any badge numbers
457
+ const dashboardContainer = dashboardTab.closest('[role="tab"]');
458
+ const badgeInDashboard = dashboardContainer
459
+ ? within(dashboardContainer).queryByText(/^(5|99)$/)
460
+ : null;
461
+ await expect(badgeInDashboard).toBeNull();
462
+ });
463
+ },
464
+ };
465
+
466
+ // 5. Disabled Tabs Test
467
+ export const DisabledTabsTest: Story = {
468
+ name: '🚫 Disabled Tabs Test',
469
+ args: {
470
+ items: [
471
+ {
472
+ id: 'tab1',
473
+ label: 'Active Tab',
474
+ content: (
475
+ <Box sx={{ p: 2 }}>
476
+ <Typography>Active content</Typography>
477
+ </Box>
478
+ ),
479
+ },
480
+ {
481
+ id: 'tab2',
482
+ label: 'Disabled Tab',
483
+ disabled: true,
484
+ content: (
485
+ <Box sx={{ p: 2 }}>
486
+ <Typography>This should not be visible</Typography>
487
+ </Box>
488
+ ),
489
+ },
490
+ {
491
+ id: 'tab3',
492
+ label: 'Another Active Tab',
493
+ content: (
494
+ <Box sx={{ p: 2 }}>
495
+ <Typography>Another active content</Typography>
496
+ </Box>
497
+ ),
498
+ },
499
+ ],
500
+ },
501
+ render: (args) => <TabsTestWrapper {...args} />,
502
+ play: async ({ canvasElement, step }) => {
503
+ const canvas = within(canvasElement);
504
+
505
+ await step('Verify disabled tab appearance', async () => {
506
+ const disabledTab = canvas.getByRole('tab', { name: /Disabled Tab/i });
507
+ await expect(disabledTab).toBeInTheDocument();
508
+ await expect(disabledTab).toHaveAttribute('aria-disabled', 'true');
509
+ });
510
+
511
+ await step('Attempt to click disabled tab', async () => {
512
+ const disabledTab = canvas.getByRole('tab', { name: /Disabled Tab/i });
513
+
514
+ // Try to click but expect it to fail gracefully due to pointer-events: none
515
+ try {
516
+ await userEvent.click(disabledTab, { skipPointerEventsCheck: true });
517
+ } catch {
518
+ // Expected to fail due to pointer-events: none
519
+ }
520
+
521
+ // Should not be selected
522
+ await expect(disabledTab).toHaveAttribute('aria-selected', 'false');
523
+
524
+ // First tab should still be selected
525
+ const firstTab = canvas.getByRole('tab', { name: 'Active Tab' });
526
+ await expect(firstTab).toHaveAttribute('aria-selected', 'true');
527
+ });
528
+
529
+ await step('Verify disabled content is not shown', async () => {
530
+ // The disabled tab's content should not be visible
531
+ const disabledContent = canvas.queryByText('This should not be visible');
532
+ await expect(disabledContent).not.toBeInTheDocument();
533
+ });
534
+ },
535
+ };
536
+
537
+ // 6. Variant Test
538
+ export const VariantTest: Story = {
539
+ name: '🎨 Variant Test',
540
+ args: {
541
+ items: itemsWithIcons,
542
+ },
543
+ render: () => {
544
+ const variants = ['default', 'pills', 'underline', 'enclosed'] as const;
545
+
546
+ return (
547
+ <Box sx={{ display: 'flex', flexDirection: 'column', gap: 4, width: 800 }}>
548
+ {variants.map((variant) => (
549
+ <Box key={variant}>
550
+ <Typography variant="h6" gutterBottom>
551
+ {variant}
552
+ </Typography>
553
+ <TabsTestWrapper items={itemsWithIcons} variant={variant} initialValue="home" />
554
+ </Box>
555
+ ))}
556
+ </Box>
557
+ );
558
+ },
559
+ play: async ({ canvasElement, step }) => {
560
+ const canvas = within(canvasElement);
561
+
562
+ await step('Verify all variants are rendered', async () => {
563
+ // Check that all variant labels are present
564
+ await expect(canvas.getByText('default')).toBeInTheDocument();
565
+ await expect(canvas.getByText('pills')).toBeInTheDocument();
566
+ await expect(canvas.getByText('underline')).toBeInTheDocument();
567
+ await expect(canvas.getByText('enclosed')).toBeInTheDocument();
568
+
569
+ // Check that tabs are rendered for each variant
570
+ const allTabs = canvas.getAllByRole('tab');
571
+ // 3 tabs × 4 variants = 12 tabs
572
+ await expect(allTabs).toHaveLength(12);
573
+ });
574
+ },
575
+ };
576
+
577
+ // 7. Size Variation Test
578
+ export const SizeVariationTest: Story = {
579
+ name: '📏 Size Variation Test',
580
+ args: {
581
+ items: basicTestItems,
582
+ onChange: fn(),
583
+ onTabClose: fn(),
584
+ onFocus: fn(),
585
+ onBlur: fn(),
586
+ },
587
+ render: (args) => {
588
+ const sizes = ['sm', 'md', 'lg'] as const;
589
+
590
+ return (
591
+ <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3, width: 600 }}>
592
+ {sizes.map((size) => (
593
+ <Box key={size}>
594
+ <Typography variant="subtitle2" gutterBottom>
595
+ Size: {size}
596
+ </Typography>
597
+ <TabsTestWrapper
598
+ items={basicTestItems}
599
+ size={size}
600
+ variant="default"
601
+ initialValue="tab1"
602
+ onChangeCallback={args.onChange}
603
+ onTabCloseCallback={args.onTabClose}
604
+ onFocusCallback={args.onFocus}
605
+ onBlurCallback={args.onBlur}
606
+ />
607
+ </Box>
608
+ ))}
609
+ </Box>
610
+ );
611
+ },
612
+ parameters: {
613
+ test: {
614
+ dangerouslyIgnoreUnhandledErrors: true,
615
+ },
616
+ },
617
+ play: async ({ canvasElement, step }) => {
618
+ const canvas = within(canvasElement);
619
+
620
+ await step('Verify all sizes are rendered', async () => {
621
+ // Check size labels
622
+ await expect(canvas.getByText('Size: sm')).toBeInTheDocument();
623
+ await expect(canvas.getByText('Size: md')).toBeInTheDocument();
624
+ await expect(canvas.getByText('Size: lg')).toBeInTheDocument();
625
+
626
+ // Check that tabs exist for each size
627
+ const allTabs = canvas.getAllByRole('tab');
628
+ // 3 tabs × 3 sizes = 9 tabs
629
+ await expect(allTabs).toHaveLength(9);
630
+ });
631
+ },
632
+ };
633
+
634
+ // 8. Scrollable Tabs Test
635
+ export const ScrollableTabsTest: Story = {
636
+ name: '📜 Scrollable Tabs Test',
637
+ args: {
638
+ scrollable: true,
639
+ items: [
640
+ ...basicTestItems,
641
+ {
642
+ id: 'tab4',
643
+ label: 'Tab 4',
644
+ content: (
645
+ <Box sx={{ p: 2 }}>
646
+ <Typography>Content 4</Typography>
647
+ </Box>
648
+ ),
649
+ },
650
+ {
651
+ id: 'tab5',
652
+ label: 'Tab 5',
653
+ content: (
654
+ <Box sx={{ p: 2 }}>
655
+ <Typography>Content 5</Typography>
656
+ </Box>
657
+ ),
658
+ },
659
+ {
660
+ id: 'tab6',
661
+ label: 'Tab 6',
662
+ content: (
663
+ <Box sx={{ p: 2 }}>
664
+ <Typography>Content 6</Typography>
665
+ </Box>
666
+ ),
667
+ },
668
+ {
669
+ id: 'tab7',
670
+ label: 'Tab 7',
671
+ content: (
672
+ <Box sx={{ p: 2 }}>
673
+ <Typography>Content 7</Typography>
674
+ </Box>
675
+ ),
676
+ },
677
+ {
678
+ id: 'tab8',
679
+ label: 'Tab 8',
680
+ content: (
681
+ <Box sx={{ p: 2 }}>
682
+ <Typography>Content 8</Typography>
683
+ </Box>
684
+ ),
685
+ },
686
+ ],
687
+ },
688
+ render: (args) => (
689
+ <Box sx={{ width: 400 }}>
690
+ <TabsTestWrapper {...args} />
691
+ </Box>
692
+ ),
693
+ play: async ({ canvasElement, step }) => {
694
+ const canvas = within(canvasElement);
695
+
696
+ await step('Verify scrollable tabs are rendered', async () => {
697
+ // Check that all tabs are rendered
698
+ const allTabs = canvas.getAllByRole('tab');
699
+ await expect(allTabs).toHaveLength(8);
700
+ });
701
+
702
+ await step('Check for scroll buttons', async () => {
703
+ // MUI adds scroll buttons when tabs overflow
704
+ // Note: Scroll buttons might not appear if all tabs fit
705
+ const tabsContainer = canvas.getByRole('tablist');
706
+ await expect(tabsContainer).toBeInTheDocument();
707
+ });
708
+ },
709
+ };
710
+
711
+ // 9. Animation Test
712
+ export const AnimationTest: Story = {
713
+ name: '🎬 Animation Test',
714
+ args: {
715
+ items: basicTestItems,
716
+ animateContent: true,
717
+ animationDuration: 300,
718
+ },
719
+ render: (args) => <TabsTestWrapper {...args} />,
720
+ play: async ({ canvasElement, step }) => {
721
+ const canvas = within(canvasElement);
722
+
723
+ await step('Switch tabs with animation', async () => {
724
+ const tab2 = canvas.getByRole('tab', { name: /Tab 2/i });
725
+
726
+ // Click tab2
727
+ await userEvent.click(tab2);
728
+
729
+ // Wait for animation to complete
730
+ await waitFor(
731
+ () => {
732
+ const panel2 = canvas.getByRole('tabpanel', { name: /Tab 2/i });
733
+ expect(panel2).toBeInTheDocument();
734
+ expect(panel2).toHaveTextContent('Content for Tab 2');
735
+ },
736
+ { timeout: 500 },
737
+ );
738
+ });
739
+
740
+ await step('Switch back with animation', async () => {
741
+ const tab1 = canvas.getByRole('tab', { name: /Tab 1/i });
742
+
743
+ // Click tab1
744
+ await userEvent.click(tab1);
745
+
746
+ // Wait for animation
747
+ await waitFor(
748
+ () => {
749
+ const panel1 = canvas.getByRole('tabpanel', { name: /Tab 1/i });
750
+ expect(panel1).toBeInTheDocument();
751
+ expect(panel1).toHaveTextContent('Content for Tab 1');
752
+ },
753
+ { timeout: 500 },
754
+ );
755
+ });
756
+ },
757
+ };
758
+
759
+ // 10. Persist Content Test
760
+ export const PersistContentTest: Story = {
761
+ name: '💾 Persist Content Test',
762
+ args: {
763
+ items: [
764
+ {
765
+ id: 'form',
766
+ label: 'Form',
767
+ content: (
768
+ <Box sx={{ p: 2 }}>
769
+ <input type="text" data-testid="form-input" placeholder="Enter text" />
770
+ </Box>
771
+ ),
772
+ },
773
+ {
774
+ id: 'settings',
775
+ label: 'Settings',
776
+ content: (
777
+ <Box sx={{ p: 2 }}>
778
+ <Typography>Settings content</Typography>
779
+ </Box>
780
+ ),
781
+ },
782
+ ],
783
+ persistContent: true,
784
+ },
785
+ render: (args) => <TabsTestWrapper {...args} initialValue="form" />,
786
+ play: async ({ canvasElement, step }) => {
787
+ const canvas = within(canvasElement);
788
+
789
+ await step('Enter text in form', async () => {
790
+ const input = canvas.getByTestId('form-input');
791
+ await userEvent.type(input, 'Test value');
792
+ await expect(input).toHaveValue('Test value');
793
+ });
794
+
795
+ await step('Switch to another tab', async () => {
796
+ const settingsTab = canvas.getByRole('tab', { name: /Settings/i });
797
+ await userEvent.click(settingsTab);
798
+
799
+ // Settings panel should be visible
800
+ const settingsPanel = canvas.getByRole('tabpanel', { name: /Settings/i });
801
+ await expect(settingsPanel).toBeInTheDocument();
802
+ });
803
+
804
+ await step('Switch back and verify form persisted', async () => {
805
+ const formTab = canvas.getByRole('tab', { name: /Form/i });
806
+ await userEvent.click(formTab);
807
+
808
+ // Check that input value is preserved
809
+ const input = canvas.getByTestId('form-input');
810
+ await expect(input).toHaveValue('Test value');
811
+ });
812
+ },
813
+ };
814
+
815
+ // 11. Loading State Test
816
+ export const LoadingStateTest: Story = {
817
+ name: '⏳ Loading State Test',
818
+ args: {
819
+ items: basicTestItems,
820
+ loading: true,
821
+ },
822
+ render: (args) => <TabsTestWrapper {...args} />,
823
+ play: async ({ canvasElement, step }) => {
824
+ const canvas = within(canvasElement);
825
+
826
+ await step('Verify loading indicator is shown', async () => {
827
+ // Check for loading spinner (CircularProgress)
828
+ const loadingIndicator = canvas.getByRole('progressbar');
829
+ await expect(loadingIndicator).toBeInTheDocument();
830
+ });
831
+
832
+ await step('Verify content is not shown while loading', async () => {
833
+ // Content should not be visible
834
+ const content = canvas.queryByText('Content for Tab 1');
835
+ await expect(content).not.toBeInTheDocument();
836
+ });
837
+ },
838
+ };
839
+
840
+ // 12. Accessibility Test
841
+ export const AccessibilityTest: Story = {
842
+ name: '♿ Accessibility Test',
843
+ args: {
844
+ items: itemsWithIcons,
845
+ },
846
+ render: (args) => <TabsTestWrapper {...args} initialValue="home" />,
847
+ parameters: {
848
+ a11y: {
849
+ element: '#storybook-root',
850
+ config: {
851
+ rules: [
852
+ { id: 'color-contrast', enabled: true },
853
+ { id: 'aria-required-attr', enabled: true },
854
+ { id: 'aria-roles', enabled: true },
855
+ { id: 'aria-valid-attr-value', enabled: true },
856
+ { id: 'button-name', enabled: true },
857
+ { id: 'tabindex', enabled: true },
858
+ ],
859
+ },
860
+ },
861
+ },
862
+ play: async ({ canvasElement, step }) => {
863
+ const canvas = within(canvasElement);
864
+
865
+ await step('Verify ARIA attributes', async () => {
866
+ // Check tablist role
867
+ const tablist = canvas.getByRole('tablist');
868
+ await expect(tablist).toBeInTheDocument();
869
+
870
+ // Check tab roles and ARIA attributes
871
+ const tabs = canvas.getAllByRole('tab');
872
+ for (const tab of tabs) {
873
+ await expect(tab).toHaveAttribute('role', 'tab');
874
+ await expect(tab).toHaveAttribute('aria-controls');
875
+ await expect(tab).toHaveAttribute('id');
876
+ }
877
+
878
+ // Check tabpanel role and ARIA attributes
879
+ const panel = canvas.getByRole('tabpanel');
880
+ await expect(panel).toHaveAttribute('role', 'tabpanel');
881
+ await expect(panel).toHaveAttribute('aria-labelledby');
882
+ await expect(panel).toHaveAttribute('id');
883
+ });
884
+
885
+ await step('Verify keyboard accessibility', async () => {
886
+ const firstTab = canvas.getByRole('tab', { name: /Home/i });
887
+
888
+ // Focus first tab
889
+ firstTab.focus();
890
+ await expect(firstTab).toHaveFocus();
891
+
892
+ // Tab key should move focus out of tablist
893
+ await userEvent.tab();
894
+ await expect(firstTab).not.toHaveFocus();
895
+
896
+ // Shift+Tab should return focus to tablist
897
+ await userEvent.tab({ shift: true });
898
+ await expect(firstTab).toHaveFocus();
899
+ });
900
+ },
901
+ };
902
+
903
+ // 13. Color Theme Test
904
+ export const ColorThemeTest: Story = {
905
+ name: '🎨 Color Theme Test',
906
+ args: {
907
+ items: basicTestItems,
908
+ },
909
+ render: () => (
910
+ <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3, width: 600 }}>
911
+ <Box>
912
+ <Typography variant="subtitle2" gutterBottom>
913
+ Primary Color
914
+ </Typography>
915
+ <TabsTestWrapper items={basicTestItems} color="primary" variant="default" />
916
+ </Box>
917
+ <Box>
918
+ <Typography variant="subtitle2" gutterBottom>
919
+ Secondary Color
920
+ </Typography>
921
+ <TabsTestWrapper items={basicTestItems} color="secondary" variant="default" />
922
+ </Box>
923
+ </Box>
924
+ ),
925
+ play: async ({ canvasElement, step }) => {
926
+ const canvas = within(canvasElement);
927
+
928
+ await step('Verify both color themes are rendered', async () => {
929
+ await expect(canvas.getByText('Primary Color')).toBeInTheDocument();
930
+ await expect(canvas.getByText('Secondary Color')).toBeInTheDocument();
931
+
932
+ // Check that tabs are rendered for both themes
933
+ const allTabs = canvas.getAllByRole('tab');
934
+ await expect(allTabs).toHaveLength(6); // 3 tabs × 2 themes
935
+ });
936
+ },
937
+ };
938
+
939
+ // 14. Full Width Test
940
+ export const FullWidthTest: Story = {
941
+ name: '↔️ Full Width Test',
942
+ args: {
943
+ items: basicTestItems.slice(0, 2),
944
+ fullWidth: true,
945
+ variant: 'default',
946
+ },
947
+ render: (args) => (
948
+ <Box sx={{ width: 800, border: '1px dashed #ccc', p: 2 }}>
949
+ <TabsTestWrapper {...args} />
950
+ </Box>
951
+ ),
952
+ play: async ({ canvasElement, step }) => {
953
+ const canvas = within(canvasElement);
954
+
955
+ await step('Verify tabs stretch full width', async () => {
956
+ const tablist = canvas.getByRole('tablist');
957
+ await expect(tablist).toBeInTheDocument();
958
+
959
+ // Tabs should be present
960
+ const tabs = canvas.getAllByRole('tab');
961
+ await expect(tabs).toHaveLength(2);
962
+ });
963
+ },
964
+ };
965
+
966
+ // 15. Centered Tabs Test
967
+ export const CenteredTabsTest: Story = {
968
+ name: '🎯 Centered Tabs Test',
969
+ args: {
970
+ items: basicTestItems.slice(0, 2),
971
+ centered: true,
972
+ variant: 'default',
973
+ },
974
+ render: (args) => (
975
+ <Box sx={{ width: 800, border: '1px dashed #ccc', p: 2 }}>
976
+ <TabsTestWrapper {...args} />
977
+ </Box>
978
+ ),
979
+ play: async ({ canvasElement, step }) => {
980
+ const canvas = within(canvasElement);
981
+
982
+ await step('Verify tabs are centered', async () => {
983
+ const tablist = canvas.getByRole('tablist');
984
+ await expect(tablist).toBeInTheDocument();
985
+
986
+ // Tabs should be present
987
+ const tabs = canvas.getAllByRole('tab');
988
+ await expect(tabs).toHaveLength(2);
989
+ });
990
+ },
991
+ };
992
+
993
+ // 16. Edge Cases Test
994
+ export const EdgeCasesTest: Story = {
995
+ name: '🔧 Edge Cases Test',
996
+ args: {
997
+ items: [
998
+ {
999
+ id: 'empty',
1000
+ label: '',
1001
+ content: <Box sx={{ p: 2 }}></Box>,
1002
+ },
1003
+ {
1004
+ id: 'long',
1005
+ label: 'This is a very long tab label that might overflow the container',
1006
+ content: (
1007
+ <Box sx={{ p: 2 }}>
1008
+ <Typography>Long label content</Typography>
1009
+ </Box>
1010
+ ),
1011
+ },
1012
+ {
1013
+ id: 'special',
1014
+ label: 'Special @#$% Characters!',
1015
+ content: (
1016
+ <Box sx={{ p: 2 }}>
1017
+ <Typography>Special characters content</Typography>
1018
+ </Box>
1019
+ ),
1020
+ },
1021
+ ],
1022
+ },
1023
+ render: (args) => (
1024
+ <Box sx={{ width: 400 }}>
1025
+ <TabsTestWrapper {...args} initialValue="long" />
1026
+ </Box>
1027
+ ),
1028
+ play: async ({ canvasElement, step }) => {
1029
+ const canvas = within(canvasElement);
1030
+
1031
+ await step('Verify edge case tabs are rendered', async () => {
1032
+ const tabs = canvas.getAllByRole('tab');
1033
+ await expect(tabs).toHaveLength(3);
1034
+
1035
+ // Check special characters tab
1036
+ const specialTab = canvas.getByRole('tab', { name: /Special.*Characters/i });
1037
+ await expect(specialTab).toBeInTheDocument();
1038
+
1039
+ // Handle empty label
1040
+ const emptyTab = tabs[0];
1041
+ await expect(emptyTab).toBeInTheDocument();
1042
+ // Even with empty label, tab should be clickable
1043
+ await userEvent.click(emptyTab);
1044
+ await expect(emptyTab).toHaveAttribute('aria-selected', 'true');
1045
+ });
1046
+ },
1047
+ };
1048
+
1049
+ // 17. Custom Indicator Color Test
1050
+ export const CustomIndicatorColorTest: Story = {
1051
+ name: '🖌️ Custom Indicator Color Test',
1052
+ args: {
1053
+ items: basicTestItems,
1054
+ variant: 'default',
1055
+ indicatorColor: '#ff6b6b',
1056
+ },
1057
+ render: (args) => <TabsTestWrapper {...args} />,
1058
+ play: async ({ canvasElement, step }) => {
1059
+ const canvas = within(canvasElement);
1060
+
1061
+ await step('Verify tabs with custom indicator are rendered', async () => {
1062
+ const tabs = canvas.getAllByRole('tab');
1063
+ await expect(tabs).toHaveLength(3);
1064
+
1065
+ // Click to switch tabs and verify indicator moves
1066
+ const tab2 = canvas.getByRole('tab', { name: /Tab 2/i });
1067
+ await userEvent.click(tab2);
1068
+ await expect(tab2).toHaveAttribute('aria-selected', 'true');
1069
+ });
1070
+ },
1071
+ };
1072
+
1073
+ // 18. Dividers Test
1074
+ export const DividersTest: Story = {
1075
+ name: '│ Dividers Test',
1076
+ args: {
1077
+ items: basicTestItems,
1078
+ showDividers: true,
1079
+ variant: 'underline',
1080
+ },
1081
+ render: (args) => <TabsTestWrapper {...args} />,
1082
+ play: async ({ canvasElement, step }) => {
1083
+ const canvas = within(canvasElement);
1084
+
1085
+ await step('Verify tabs with dividers are rendered', async () => {
1086
+ const tabs = canvas.getAllByRole('tab');
1087
+ await expect(tabs).toHaveLength(3);
1088
+
1089
+ // Tabs should be functional
1090
+ const tab2 = canvas.getByRole('tab', { name: /Tab 2/i });
1091
+ await userEvent.click(tab2);
1092
+ await expect(tab2).toHaveAttribute('aria-selected', 'true');
1093
+ });
1094
+ },
1095
+ };
1096
+
1097
+ // 19. Comprehensive Integration Test
1098
+ export const IntegrationTest: Story = {
1099
+ name: '🔗 Integration Test',
1100
+ args: {
1101
+ variant: 'pills',
1102
+ size: 'md',
1103
+ color: 'primary',
1104
+ animateContent: true,
1105
+ onChange: fn(),
1106
+ onTabClose: fn(),
1107
+ onFocus: fn(),
1108
+ onBlur: fn(),
1109
+ items: [
1110
+ {
1111
+ id: 'home',
1112
+ label: 'Home',
1113
+ icon: <Home />,
1114
+ badge: 2,
1115
+ content: (
1116
+ <Box sx={{ p: 2 }}>
1117
+ <Typography>Home with notifications</Typography>
1118
+ </Box>
1119
+ ),
1120
+ },
1121
+ {
1122
+ id: 'security',
1123
+ label: 'Security',
1124
+ icon: <Security />,
1125
+ disabled: true,
1126
+ content: (
1127
+ <Box sx={{ p: 2 }}>
1128
+ <Typography>Security (disabled)</Typography>
1129
+ </Box>
1130
+ ),
1131
+ },
1132
+ {
1133
+ id: 'settings',
1134
+ label: 'Settings',
1135
+ icon: <Settings />,
1136
+ closable: true,
1137
+ content: (
1138
+ <Box sx={{ p: 2 }}>
1139
+ <Typography>Closable settings</Typography>
1140
+ </Box>
1141
+ ),
1142
+ },
1143
+ ],
1144
+ },
1145
+ render: (args) => {
1146
+ const IntegrationWrapper = () => {
1147
+ const [items, setItems] = useState(args.items);
1148
+ const [value, setValue] = useState('home');
1149
+
1150
+ const handleChange = (event: React.SyntheticEvent, tabId: string) => {
1151
+ setValue(tabId);
1152
+ args.onChange(event, tabId);
1153
+ };
1154
+
1155
+ const handleTabClose = (tabId: string) => {
1156
+ const newItems = items.filter((item) => item.id !== tabId);
1157
+ setItems(newItems);
1158
+ if (value === tabId && newItems.length > 0) {
1159
+ setValue(newItems[0].id);
1160
+ }
1161
+ args.onTabClose(tabId);
1162
+ };
1163
+
1164
+ return (
1165
+ <Box sx={{ width: 600, minHeight: 300 }}>
1166
+ <Tabs
1167
+ {...args}
1168
+ items={items}
1169
+ value={value}
1170
+ onChange={handleChange}
1171
+ onTabClose={handleTabClose}
1172
+ onFocus={args.onFocus}
1173
+ onBlur={args.onBlur}
1174
+ />
1175
+ </Box>
1176
+ );
1177
+ };
1178
+
1179
+ return <IntegrationWrapper />;
1180
+ },
1181
+ play: async ({ canvasElement, step }) => {
1182
+ const canvas = within(canvasElement);
1183
+
1184
+ await step('Verify all features work together', async () => {
1185
+ // Check badge
1186
+ await expect(canvas.getByText('2')).toBeInTheDocument();
1187
+
1188
+ // Check disabled tab
1189
+ const securityTab = canvas.getByRole('tab', { name: /Security/i });
1190
+ await expect(securityTab).toHaveAttribute('aria-disabled', 'true');
1191
+
1192
+ // Check closable tab has close button
1193
+ const closeButtons = canvas.getAllByRole('button', { name: 'Close tab' });
1194
+ await expect(closeButtons.length).toBeGreaterThan(0);
1195
+ });
1196
+
1197
+ await step('Test tab switching with animation', async () => {
1198
+ const settingsTab = canvas.getByRole('tab', { name: /Settings/i });
1199
+ await userEvent.click(settingsTab);
1200
+
1201
+ // Wait for animation
1202
+ await waitFor(() => {
1203
+ const panel = canvas.getByRole('tabpanel');
1204
+ expect(panel).toHaveTextContent('Closable settings');
1205
+ });
1206
+ });
1207
+
1208
+ await step('Close the settings tab', async () => {
1209
+ const closeButtons = canvas.getAllByRole('button', { name: 'Close tab' });
1210
+ const settingsCloseButton = closeButtons[0];
1211
+
1212
+ await userEvent.click(settingsCloseButton);
1213
+
1214
+ // Wait for tab to be removed
1215
+ await waitFor(() => {
1216
+ const settingsTab = canvas.queryByRole('tab', { name: /Settings/i });
1217
+ expect(settingsTab).not.toBeInTheDocument();
1218
+ });
1219
+
1220
+ // Should switch to home tab
1221
+ const homeTab = canvas.getByRole('tab', { name: /Home/i });
1222
+ await expect(homeTab).toHaveAttribute('aria-selected', 'true');
1223
+ });
1224
+ },
1225
+ };