@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,1339 @@
1
+ import { Dashboard,Home, Menu as MenuIcon, Person, Settings } from '@mui/icons-material';
2
+ import {
3
+ Box,
4
+ Button,
5
+ IconButton,
6
+ List,
7
+ ListItemButton,
8
+ ListItemIcon,
9
+ ListItemText,
10
+ Stack,
11
+ Typography,
12
+ } from '@mui/material';
13
+ import type { Meta, StoryObj } from '@storybook/react-vite';
14
+ import { useState } from 'react';
15
+ import { expect, fn,userEvent, waitFor, within } from 'storybook/test';
16
+
17
+ import { Drawer, DrawerContent,DrawerHeader } from './Drawer';
18
+
19
+ const meta: Meta<typeof Drawer> = {
20
+ title: 'Layout/Drawer/Tests',
21
+ component: Drawer,
22
+ parameters: {
23
+ layout: 'fullscreen',
24
+ chromatic: { disableSnapshot: false },
25
+ },
26
+ tags: ['autodocs', 'test', 'component:Drawer'],
27
+ };
28
+
29
+ export default meta;
30
+ type Story = StoryObj<typeof meta>;
31
+
32
+ // Basic Interaction Tests
33
+ export const BasicInteraction: Story = {
34
+ name: '🧪 Basic Interaction',
35
+ render: () => {
36
+ const BasicInteractionComponent = () => {
37
+ const [open, setOpen] = useState(false);
38
+ const [interactionState, setInteractionState] = useState('closed');
39
+ const handleOpen = fn(() => {
40
+ setOpen(true);
41
+ setInteractionState('opened');
42
+ });
43
+ const handleClose = fn(() => {
44
+ setOpen(false);
45
+ setInteractionState('closed');
46
+ });
47
+
48
+ return (
49
+ <Box sx={{ height: '100vh', position: 'relative' }}>
50
+ <Button
51
+ data-testid="open-drawer-button"
52
+ onClick={handleOpen}
53
+ sx={{ position: 'fixed', top: 16, left: 16, zIndex: 1300 }}
54
+ >
55
+ Open Drawer
56
+ </Button>
57
+ <Typography data-testid="interaction-state" sx={{ position: 'fixed', top: 60, left: 16 }}>
58
+ State: {interactionState}
59
+ </Typography>
60
+ <Drawer open={open} onClose={handleClose} data-testid="drawer">
61
+ <DrawerHeader onClose={handleClose}>
62
+ <Typography variant="h6">Test Drawer</Typography>
63
+ </DrawerHeader>
64
+ <DrawerContent>
65
+ <List>
66
+ <ListItemButton data-testid="nav-item-home">
67
+ <ListItemIcon>
68
+ <Home />
69
+ </ListItemIcon>
70
+ <ListItemText primary="Home" />
71
+ </ListItemButton>
72
+ <ListItemButton data-testid="nav-item-settings">
73
+ <ListItemIcon>
74
+ <Settings />
75
+ </ListItemIcon>
76
+ <ListItemText primary="Settings" />
77
+ </ListItemButton>
78
+ </List>
79
+ </DrawerContent>
80
+ </Drawer>
81
+ </Box>
82
+ );
83
+ };
84
+
85
+ return <BasicInteractionComponent />;
86
+ },
87
+ play: async ({ canvasElement }) => {
88
+ const canvas = within(canvasElement);
89
+
90
+ // Test drawer opens
91
+ const openButton = canvas.getByTestId('open-drawer-button');
92
+ expect(openButton).toBeInTheDocument();
93
+
94
+ // Verify initial state
95
+ const stateIndicator = canvas.getByTestId('interaction-state');
96
+ expect(stateIndicator).toHaveTextContent('State: closed');
97
+
98
+ await userEvent.click(openButton);
99
+
100
+ // Verify state change after opening
101
+ await waitFor(() => {
102
+ expect(stateIndicator).toHaveTextContent('State: opened');
103
+ });
104
+
105
+ // Test that MUI backdrop is rendered (drawer is open)
106
+ await waitFor(() => {
107
+ const backdrop = document.querySelector('.MuiBackdrop-root');
108
+ expect(backdrop).toBeInTheDocument();
109
+ });
110
+
111
+ // Test ESC key closes drawer
112
+ await userEvent.keyboard('{Escape}');
113
+
114
+ await waitFor(() => {
115
+ expect(stateIndicator).toHaveTextContent('State: closed');
116
+ });
117
+ },
118
+ };
119
+
120
+ // Keyboard Navigation Tests
121
+ export const KeyboardNavigation: Story = {
122
+ name: '⌨️ Keyboard Navigation',
123
+ render: () => {
124
+ const KeyboardNavigationComponent = () => {
125
+ const [open, setOpen] = useState(false);
126
+ const [keyboardState, setKeyboardState] = useState('ready');
127
+ const handleOpen = fn(() => setOpen(true));
128
+ const handleClose = fn(() => {
129
+ setOpen(false);
130
+ setKeyboardState('closed-by-escape');
131
+ });
132
+
133
+ return (
134
+ <Box sx={{ height: '100vh', position: 'relative' }}>
135
+ <Button
136
+ data-testid="kbd-open-button"
137
+ onClick={handleOpen}
138
+ sx={{ position: 'fixed', top: 16, left: 16, zIndex: 1300 }}
139
+ >
140
+ Open for Keyboard Test
141
+ </Button>
142
+ <Typography data-testid="keyboard-state" sx={{ position: 'fixed', top: 60, left: 16 }}>
143
+ Keyboard State: {keyboardState}
144
+ </Typography>
145
+ <Drawer open={open} onClose={handleClose} data-testid="keyboard-drawer">
146
+ <DrawerHeader onClose={handleClose}>
147
+ <Typography variant="h6">Keyboard Navigation</Typography>
148
+ </DrawerHeader>
149
+ <DrawerContent>
150
+ <List>
151
+ <ListItemButton data-testid="kbd-nav-home">
152
+ <ListItemIcon>
153
+ <Home />
154
+ </ListItemIcon>
155
+ <ListItemText primary="Home" />
156
+ </ListItemButton>
157
+ <ListItemButton data-testid="kbd-nav-dashboard">
158
+ <ListItemIcon>
159
+ <Dashboard />
160
+ </ListItemIcon>
161
+ <ListItemText primary="Dashboard" />
162
+ </ListItemButton>
163
+ <ListItemButton data-testid="kbd-nav-settings">
164
+ <ListItemIcon>
165
+ <Settings />
166
+ </ListItemIcon>
167
+ <ListItemText primary="Settings" />
168
+ </ListItemButton>
169
+ <ListItemButton data-testid="kbd-nav-profile">
170
+ <ListItemIcon>
171
+ <Person />
172
+ </ListItemIcon>
173
+ <ListItemText primary="Profile" />
174
+ </ListItemButton>
175
+ </List>
176
+ </DrawerContent>
177
+ </Drawer>
178
+ </Box>
179
+ );
180
+ };
181
+
182
+ return <KeyboardNavigationComponent />;
183
+ },
184
+ play: async ({ canvasElement }) => {
185
+ const canvas = within(canvasElement);
186
+
187
+ // Test opening drawer
188
+ const openButton = canvas.getByTestId('kbd-open-button');
189
+ expect(openButton).toBeInTheDocument();
190
+
191
+ await userEvent.click(openButton);
192
+
193
+ // Test that backdrop appears (drawer is open)
194
+ await waitFor(() => {
195
+ const backdrop = document.querySelector('.MuiBackdrop-root');
196
+ expect(backdrop).toBeInTheDocument();
197
+ });
198
+
199
+ // Test Escape key closes drawer
200
+ await userEvent.keyboard('{Escape}');
201
+
202
+ await waitFor(() => {
203
+ const stateIndicator = canvas.getByTestId('keyboard-state');
204
+ expect(stateIndicator).toHaveTextContent('Keyboard State: closed-by-escape');
205
+ });
206
+
207
+ // Verify drawer is closed (no backdrop)
208
+ await waitFor(() => {
209
+ const backdrop = document.querySelector('.MuiBackdrop-root');
210
+ expect(backdrop).not.toBeInTheDocument();
211
+ });
212
+ },
213
+ };
214
+
215
+ // Screen Reader Accessibility Tests
216
+ export const ScreenReader: Story = {
217
+ name: '🔊 Screen Reader',
218
+ render: () => {
219
+ const ScreenReaderComponent = () => {
220
+ const [open, setOpen] = useState(true);
221
+
222
+ return (
223
+ <Box sx={{ height: '100vh', position: 'relative' }}>
224
+ <Drawer
225
+ open={open}
226
+ onClose={() => setOpen(false)}
227
+ data-testid="sr-drawer"
228
+ aria-labelledby="drawer-title"
229
+ role="navigation"
230
+ >
231
+ <DrawerHeader onClose={() => setOpen(false)}>
232
+ <Typography id="drawer-title" variant="h6">
233
+ Main Navigation
234
+ </Typography>
235
+ </DrawerHeader>
236
+ <DrawerContent>
237
+ <List role="menu" aria-labelledby="drawer-title">
238
+ <ListItemButton role="menuitem" data-testid="sr-nav-home">
239
+ <ListItemIcon aria-hidden="true">
240
+ <Home />
241
+ </ListItemIcon>
242
+ <ListItemText primary="Home" />
243
+ </ListItemButton>
244
+ <ListItemButton role="menuitem" data-testid="sr-nav-dashboard">
245
+ <ListItemIcon aria-hidden="true">
246
+ <Dashboard />
247
+ </ListItemIcon>
248
+ <ListItemText primary="Dashboard" />
249
+ </ListItemButton>
250
+ <ListItemButton role="menuitem" data-testid="sr-nav-settings">
251
+ <ListItemIcon aria-hidden="true">
252
+ <Settings />
253
+ </ListItemIcon>
254
+ <ListItemText primary="Settings" />
255
+ </ListItemButton>
256
+ </List>
257
+ </DrawerContent>
258
+ </Drawer>
259
+ </Box>
260
+ );
261
+ };
262
+
263
+ return <ScreenReaderComponent />;
264
+ },
265
+ play: async () => {
266
+ // Wait for drawer to be rendered (check for backdrop first, then content)
267
+ await waitFor(
268
+ () => {
269
+ const backdrop = document.querySelector('.MuiBackdrop-root');
270
+ expect(backdrop).toBeInTheDocument();
271
+ },
272
+ { timeout: 5000 },
273
+ );
274
+
275
+ await waitFor(
276
+ () => {
277
+ const title = document.querySelector('h6');
278
+ expect(title).toBeInTheDocument();
279
+ expect(title).toHaveTextContent('Main Navigation');
280
+ },
281
+ { timeout: 5000 },
282
+ );
283
+
284
+ // Test ARIA attributes on the drawer (look in document since MUI renders in portal)
285
+ const drawer = document.querySelector('[data-testid="sr-drawer"]');
286
+ expect(drawer).toBeInTheDocument();
287
+ expect(drawer).toHaveAttribute('role', 'navigation');
288
+ expect(drawer).toHaveAttribute('aria-labelledby', 'drawer-title');
289
+
290
+ // Test drawer title
291
+ const title = document.querySelector('#drawer-title');
292
+ expect(title).toBeInTheDocument();
293
+ expect(title).toHaveTextContent('Main Navigation');
294
+
295
+ // Test navigation list
296
+ const navList = document.querySelector('[role="menu"]');
297
+ expect(navList).toBeInTheDocument();
298
+ expect(navList).toHaveAttribute('aria-labelledby', 'drawer-title');
299
+
300
+ // Test menu items
301
+ const menuItems = document.querySelectorAll('[role="menuitem"]');
302
+ expect(menuItems).toHaveLength(3);
303
+
304
+ // Test icons are hidden from screen readers
305
+ const icons = document.querySelectorAll('[aria-hidden="true"]');
306
+ expect(icons.length).toBeGreaterThan(0);
307
+
308
+ // Test close button accessibility
309
+ const closeButton = document.querySelector('button[aria-label*="close" i]');
310
+ expect(closeButton).toBeInTheDocument();
311
+ },
312
+ };
313
+
314
+ // Focus Management Tests
315
+ export const FocusManagement: Story = {
316
+ name: '🎯 Focus Management',
317
+ render: () => {
318
+ const FocusManagementComponent = () => {
319
+ const [open, setOpen] = useState(false);
320
+
321
+ return (
322
+ <Box sx={{ height: '100vh', position: 'relative' }}>
323
+ <Button
324
+ data-testid="focus-open-button"
325
+ onClick={() => setOpen(true)}
326
+ sx={{ position: 'fixed', top: 16, left: 16, zIndex: 1300 }}
327
+ >
328
+ Open Drawer
329
+ </Button>
330
+ <Drawer
331
+ open={open}
332
+ onClose={() => setOpen(false)}
333
+ data-testid="focus-drawer"
334
+ keepMounted={false}
335
+ >
336
+ <DrawerHeader onClose={() => setOpen(false)}>
337
+ <Typography variant="h6">Focus Test</Typography>
338
+ </DrawerHeader>
339
+ <DrawerContent>
340
+ <List>
341
+ <ListItemButton data-testid="focus-first-item">
342
+ <ListItemIcon>
343
+ <Home />
344
+ </ListItemIcon>
345
+ <ListItemText primary="First Item" />
346
+ </ListItemButton>
347
+ <ListItemButton data-testid="focus-second-item">
348
+ <ListItemIcon>
349
+ <Dashboard />
350
+ </ListItemIcon>
351
+ <ListItemText primary="Second Item" />
352
+ </ListItemButton>
353
+ </List>
354
+ </DrawerContent>
355
+ </Drawer>
356
+ <Box sx={{ p: 3, pt: 10 }}>
357
+ <Button data-testid="focus-main-button">Main Content Button</Button>
358
+ </Box>
359
+ </Box>
360
+ );
361
+ };
362
+
363
+ return <FocusManagementComponent />;
364
+ },
365
+ play: async ({ canvasElement }) => {
366
+ const canvas = within(canvasElement);
367
+
368
+ // Test initial focus on main content
369
+ const mainButton = canvas.getByTestId('focus-main-button');
370
+ const openButton = canvas.getByTestId('focus-open-button');
371
+
372
+ // Focus should be manageable on main content
373
+ mainButton.focus();
374
+ expect(document.activeElement).toBe(mainButton);
375
+
376
+ // Open drawer
377
+ await userEvent.click(openButton);
378
+
379
+ await waitFor(() => {
380
+ const drawerContent = document.querySelector('h6');
381
+ expect(drawerContent).toBeInTheDocument();
382
+ expect(drawerContent).toHaveTextContent('Focus Test');
383
+ });
384
+
385
+ // Test focus trap within drawer
386
+ const firstItem = document.querySelector('[data-testid="focus-first-item"]');
387
+ const secondItem = document.querySelector('[data-testid="focus-second-item"]');
388
+ const closeButton = document.querySelector('button[aria-label*="close" i]');
389
+
390
+ // Tab through drawer elements
391
+ expect(firstItem).toBeInTheDocument();
392
+ expect(secondItem).toBeInTheDocument();
393
+ expect(closeButton).toBeInTheDocument();
394
+
395
+ firstItem.focus();
396
+ expect(document.activeElement).toBe(firstItem);
397
+
398
+ await userEvent.tab();
399
+ expect(document.activeElement).toBe(secondItem);
400
+
401
+ await userEvent.tab();
402
+ expect(document.activeElement).toBe(closeButton);
403
+
404
+ // Close drawer and verify focus returns
405
+ await userEvent.click(closeButton);
406
+
407
+ await waitFor(() => {
408
+ expect(document.querySelector('h6')).not.toBeInTheDocument();
409
+ });
410
+ },
411
+ };
412
+
413
+ // Responsive Design Tests
414
+ export const ResponsiveDesign: Story = {
415
+ name: '📱 Responsive Design',
416
+ render: () => {
417
+ const ResponsiveComponent = () => {
418
+ const [open, setOpen] = useState(true);
419
+
420
+ return (
421
+ <Box sx={{ height: '100vh', position: 'relative' }}>
422
+ <Drawer
423
+ open={open}
424
+ onClose={() => setOpen(false)}
425
+ data-testid="responsive-drawer"
426
+ width={280}
427
+ >
428
+ <DrawerHeader onClose={() => setOpen(false)}>
429
+ <Typography variant="h6">Responsive Drawer</Typography>
430
+ </DrawerHeader>
431
+ <DrawerContent>
432
+ <Typography variant="body2" sx={{ p: 2 }}>
433
+ This drawer should adapt to different screen sizes.
434
+ </Typography>
435
+ <List>
436
+ <ListItemButton>
437
+ <ListItemIcon>
438
+ <Home />
439
+ </ListItemIcon>
440
+ <ListItemText primary="Home" />
441
+ </ListItemButton>
442
+ <ListItemButton>
443
+ <ListItemIcon>
444
+ <Settings />
445
+ </ListItemIcon>
446
+ <ListItemText primary="Settings" />
447
+ </ListItemButton>
448
+ </List>
449
+ </DrawerContent>
450
+ </Drawer>
451
+ </Box>
452
+ );
453
+ };
454
+
455
+ return <ResponsiveComponent />;
456
+ },
457
+ parameters: {
458
+ viewport: {
459
+ viewports: {
460
+ mobile: { name: 'Mobile', styles: { width: '375px', height: '667px' } },
461
+ tablet: { name: 'Tablet', styles: { width: '768px', height: '1024px' } },
462
+ desktop: { name: 'Desktop', styles: { width: '1024px', height: '768px' } },
463
+ },
464
+ },
465
+ },
466
+ play: async () => {
467
+ // Wait for drawer to be rendered
468
+ await waitFor(
469
+ () => {
470
+ const backdrop = document.querySelector('.MuiBackdrop-root');
471
+ expect(backdrop).toBeInTheDocument();
472
+ },
473
+ { timeout: 5000 },
474
+ );
475
+
476
+ // Test drawer renders properly (look in document since MUI renders in portal)
477
+ const drawer = document.querySelector('[data-testid="responsive-drawer"]');
478
+ expect(drawer).toBeInTheDocument();
479
+ const drawerPaper = drawer.querySelector('.MuiDrawer-paper');
480
+ expect(drawerPaper).toBeInTheDocument();
481
+
482
+ // Test drawer content is accessible (look in document since it's in portal)
483
+ await waitFor(() => {
484
+ const title = document.querySelector('h6');
485
+ expect(title).toBeInTheDocument();
486
+ expect(title).toHaveTextContent('Responsive Drawer');
487
+ });
488
+
489
+ const description = Array.from(document.querySelectorAll('*')).find((el) =>
490
+ el.textContent?.includes('This drawer should adapt to different screen sizes'),
491
+ );
492
+ expect(description).toBeInTheDocument();
493
+
494
+ // Test navigation items are present
495
+ const homeItem = Array.from(document.querySelectorAll('*')).find(
496
+ (el) => el.textContent === 'Home',
497
+ );
498
+ const settingsItem = Array.from(document.querySelectorAll('*')).find(
499
+ (el) => el.textContent === 'Settings',
500
+ );
501
+
502
+ expect(homeItem).toBeInTheDocument();
503
+ expect(settingsItem).toBeInTheDocument();
504
+ },
505
+ };
506
+
507
+ // Theme Variations Tests
508
+ export const ThemeVariations: Story = {
509
+ name: '🎨 Theme Variations',
510
+ render: () => {
511
+ const ThemeVariationsComponent = () => {
512
+ const [openDrawers, setOpenDrawers] = useState({
513
+ default: true,
514
+ glass: false,
515
+ });
516
+
517
+ const toggleDrawer = (type: keyof typeof openDrawers) => {
518
+ setOpenDrawers((prev) => ({ ...prev, [type]: !prev[type] }));
519
+ };
520
+
521
+ return (
522
+ <Box sx={{ height: '100vh', position: 'relative' }}>
523
+ <Stack direction="row" spacing={2} sx={{ p: 2, zIndex: 1300, position: 'relative' }}>
524
+ <Button
525
+ variant="outlined"
526
+ onClick={() => toggleDrawer('glass')}
527
+ data-testid="theme-glass-button"
528
+ >
529
+ Toggle Glass Theme
530
+ </Button>
531
+ </Stack>
532
+
533
+ {/* Default Theme Drawer */}
534
+ <Drawer
535
+ open={openDrawers.default}
536
+ onClose={() => toggleDrawer('default')}
537
+ data-testid="theme-default-drawer"
538
+ width={280}
539
+ >
540
+ <DrawerHeader onClose={() => toggleDrawer('default')}>
541
+ <Typography variant="h6">Default Theme</Typography>
542
+ </DrawerHeader>
543
+ <DrawerContent>
544
+ <Typography variant="body2" sx={{ p: 2 }}>
545
+ This drawer uses the default theme styling.
546
+ </Typography>
547
+ <List>
548
+ <ListItemButton>
549
+ <ListItemIcon>
550
+ <Home />
551
+ </ListItemIcon>
552
+ <ListItemText primary="Home" />
553
+ </ListItemButton>
554
+ </List>
555
+ </DrawerContent>
556
+ </Drawer>
557
+
558
+ {/* Glass Theme Drawer */}
559
+ <Drawer
560
+ open={openDrawers.glass}
561
+ onClose={() => toggleDrawer('glass')}
562
+ data-testid="theme-glass-drawer"
563
+ variant="glass"
564
+ width={300}
565
+ >
566
+ <DrawerHeader onClose={() => toggleDrawer('glass')}>
567
+ <Typography variant="h6">Glass Theme</Typography>
568
+ </DrawerHeader>
569
+ <DrawerContent>
570
+ <Typography variant="body2" sx={{ p: 2 }}>
571
+ This drawer uses glass morphism styling with backdrop blur.
572
+ </Typography>
573
+ <List>
574
+ <ListItemButton>
575
+ <ListItemIcon>
576
+ <Settings />
577
+ </ListItemIcon>
578
+ <ListItemText primary="Settings" />
579
+ </ListItemButton>
580
+ </List>
581
+ </DrawerContent>
582
+ </Drawer>
583
+ </Box>
584
+ );
585
+ };
586
+
587
+ return <ThemeVariationsComponent />;
588
+ },
589
+ play: async ({ canvasElement }) => {
590
+ const canvas = within(canvasElement);
591
+
592
+ // Wait for default theme drawer to render
593
+ await waitFor(
594
+ () => {
595
+ const backdrop = document.querySelector('.MuiBackdrop-root');
596
+ expect(backdrop).toBeInTheDocument();
597
+ },
598
+ { timeout: 5000 },
599
+ );
600
+
601
+ // Test default theme drawer (look in document since MUI renders in portal)
602
+ const defaultDrawer = document.querySelector('[data-testid="theme-default-drawer"]');
603
+ expect(defaultDrawer).toBeInTheDocument();
604
+
605
+ await waitFor(() => {
606
+ const defaultTitle = document.querySelector('h6');
607
+ expect(defaultTitle).toBeInTheDocument();
608
+ expect(defaultTitle).toHaveTextContent('Default Theme');
609
+ });
610
+
611
+ // Test glass theme toggle
612
+ const glassButton = canvas.getByTestId('theme-glass-button');
613
+ await userEvent.click(glassButton);
614
+
615
+ await waitFor(() => {
616
+ const glassDrawer = document.querySelector('[data-testid="theme-glass-drawer"]');
617
+ expect(glassDrawer).toBeInTheDocument();
618
+ });
619
+
620
+ await waitFor(() => {
621
+ const glassDrawer = document.querySelector('[data-testid="theme-glass-drawer"]');
622
+ expect(glassDrawer).toBeInTheDocument();
623
+ const glassTitle = glassDrawer.querySelector('h6');
624
+ expect(glassTitle).toBeInTheDocument();
625
+ expect(glassTitle).toHaveTextContent('Glass Theme');
626
+ });
627
+
628
+ // Test glass drawer styling
629
+ const glassDrawerElement = document.querySelector('[data-testid="theme-glass-drawer"]');
630
+ const glassDrawerPaper = glassDrawerElement.querySelector('.MuiDrawer-paper');
631
+ expect(glassDrawerPaper).toBeInTheDocument();
632
+ },
633
+ };
634
+
635
+ // Visual States Tests
636
+ export const VisualStates: Story = {
637
+ name: '👁️ Visual States',
638
+ render: () => {
639
+ const VisualStatesComponent = () => {
640
+ const [states, setStates] = useState({
641
+ left: true,
642
+ right: false,
643
+ top: false,
644
+ bottom: false,
645
+ });
646
+
647
+ const toggleState = (state: keyof typeof states) => {
648
+ setStates((prev) => ({ ...prev, [state]: !prev[state] }));
649
+ };
650
+
651
+ return (
652
+ <Box sx={{ height: '100vh', position: 'relative' }}>
653
+ <Stack direction="row" spacing={1} sx={{ p: 2, zIndex: 1300, position: 'relative' }}>
654
+ <Button
655
+ size="small"
656
+ onClick={() => toggleState('right')}
657
+ data-testid="visual-right-btn"
658
+ >
659
+ Right
660
+ </Button>
661
+ <Button size="small" onClick={() => toggleState('top')} data-testid="visual-top-btn">
662
+ Top
663
+ </Button>
664
+ <Button
665
+ size="small"
666
+ onClick={() => toggleState('bottom')}
667
+ data-testid="visual-bottom-btn"
668
+ >
669
+ Bottom
670
+ </Button>
671
+ </Stack>
672
+
673
+ {/* Left Drawer */}
674
+ <Drawer
675
+ open={states.left}
676
+ onClose={() => toggleState('left')}
677
+ variant="left"
678
+ data-testid="visual-left-drawer"
679
+ >
680
+ <DrawerHeader onClose={() => toggleState('left')}>
681
+ <Typography variant="h6">Left Drawer</Typography>
682
+ </DrawerHeader>
683
+ <DrawerContent>
684
+ <Typography variant="body2">Left side content</Typography>
685
+ </DrawerContent>
686
+ </Drawer>
687
+
688
+ {/* Right Drawer */}
689
+ <Drawer
690
+ open={states.right}
691
+ onClose={() => toggleState('right')}
692
+ variant="right"
693
+ data-testid="visual-right-drawer"
694
+ >
695
+ <DrawerHeader onClose={() => toggleState('right')}>
696
+ <Typography variant="h6">Right Drawer</Typography>
697
+ </DrawerHeader>
698
+ <DrawerContent>
699
+ <Typography variant="body2">Right side content</Typography>
700
+ </DrawerContent>
701
+ </Drawer>
702
+
703
+ {/* Top Drawer */}
704
+ <Drawer
705
+ open={states.top}
706
+ onClose={() => toggleState('top')}
707
+ variant="top"
708
+ height={200}
709
+ data-testid="visual-top-drawer"
710
+ >
711
+ <DrawerHeader onClose={() => toggleState('top')}>
712
+ <Typography variant="h6">Top Drawer</Typography>
713
+ </DrawerHeader>
714
+ <DrawerContent>
715
+ <Typography variant="body2">Top content</Typography>
716
+ </DrawerContent>
717
+ </Drawer>
718
+
719
+ {/* Bottom Drawer */}
720
+ <Drawer
721
+ open={states.bottom}
722
+ onClose={() => toggleState('bottom')}
723
+ variant="bottom"
724
+ height={200}
725
+ data-testid="visual-bottom-drawer"
726
+ >
727
+ <DrawerHeader onClose={() => toggleState('bottom')}>
728
+ <Typography variant="h6">Bottom Drawer</Typography>
729
+ </DrawerHeader>
730
+ <DrawerContent>
731
+ <Typography variant="body2">Bottom content</Typography>
732
+ </DrawerContent>
733
+ </Drawer>
734
+ </Box>
735
+ );
736
+ };
737
+
738
+ return <VisualStatesComponent />;
739
+ },
740
+ play: async ({ canvasElement }) => {
741
+ const canvas = within(canvasElement);
742
+
743
+ // Wait for left drawer to render (initially open)
744
+ await waitFor(
745
+ () => {
746
+ const backdrop = document.querySelector('.MuiBackdrop-root');
747
+ expect(backdrop).toBeInTheDocument();
748
+ },
749
+ { timeout: 5000 },
750
+ );
751
+
752
+ // Test left drawer (initially open) - look in document since MUI renders in portal
753
+ const leftDrawer = document.querySelector('[data-testid="visual-left-drawer"]');
754
+ expect(leftDrawer).toBeInTheDocument();
755
+
756
+ await waitFor(() => {
757
+ const leftTitle = leftDrawer.querySelector('h6');
758
+ expect(leftTitle).toBeInTheDocument();
759
+ expect(leftTitle).toHaveTextContent('Left Drawer');
760
+ });
761
+
762
+ // Test right drawer toggle
763
+ const rightButton = canvas.getByTestId('visual-right-btn');
764
+ await userEvent.click(rightButton);
765
+
766
+ await waitFor(() => {
767
+ const rightDrawer = document.querySelector('[data-testid="visual-right-drawer"]');
768
+ expect(rightDrawer).toBeInTheDocument();
769
+ const rightTitle = rightDrawer.querySelector('h6');
770
+ expect(rightTitle).toBeInTheDocument();
771
+ expect(rightTitle).toHaveTextContent('Right Drawer');
772
+ });
773
+
774
+ // Test top drawer toggle
775
+ const topButton = canvas.getByTestId('visual-top-btn');
776
+ await userEvent.click(topButton);
777
+
778
+ await waitFor(() => {
779
+ const topDrawer = document.querySelector('[data-testid="visual-top-drawer"]');
780
+ expect(topDrawer).toBeInTheDocument();
781
+ const topTitle = topDrawer.querySelector('h6');
782
+ expect(topTitle).toBeInTheDocument();
783
+ expect(topTitle).toHaveTextContent('Top Drawer');
784
+ });
785
+
786
+ // Test bottom drawer toggle
787
+ const bottomButton = canvas.getByTestId('visual-bottom-btn');
788
+ await userEvent.click(bottomButton);
789
+
790
+ await waitFor(() => {
791
+ const bottomDrawer = document.querySelector('[data-testid="visual-bottom-drawer"]');
792
+ expect(bottomDrawer).toBeInTheDocument();
793
+ const bottomTitle = bottomDrawer.querySelector('h6');
794
+ expect(bottomTitle).toBeInTheDocument();
795
+ expect(bottomTitle).toHaveTextContent('Bottom Drawer');
796
+ });
797
+ },
798
+ };
799
+
800
+ // Performance Tests
801
+ export const Performance: Story = {
802
+ name: '⚡ Performance',
803
+ render: () => {
804
+ const PerformanceComponent = () => {
805
+ const [open, setOpen] = useState(true);
806
+ const [itemCount, setItemCount] = useState(50);
807
+
808
+ // Generate large list of items
809
+ const items = Array.from({ length: itemCount }, (_, i) => ({
810
+ id: i,
811
+ label: `Item ${i + 1}`,
812
+ icon: i % 3 === 0 ? <Home /> : i % 3 === 1 ? <Settings /> : <Person />,
813
+ }));
814
+
815
+ return (
816
+ <Box sx={{ height: '100vh', position: 'relative' }}>
817
+ <Stack direction="row" spacing={2} sx={{ p: 2, zIndex: 1300, position: 'relative' }}>
818
+ <Button size="small" onClick={() => setItemCount(100)} data-testid="perf-100-items">
819
+ 100 Items
820
+ </Button>
821
+ <Button size="small" onClick={() => setItemCount(200)} data-testid="perf-200-items">
822
+ 200 Items
823
+ </Button>
824
+ </Stack>
825
+
826
+ <Drawer
827
+ open={open}
828
+ onClose={() => setOpen(false)}
829
+ data-testid="performance-drawer"
830
+ keepMounted={true}
831
+ >
832
+ <DrawerHeader onClose={() => setOpen(false)}>
833
+ <Typography variant="h6">Performance Test ({itemCount} items)</Typography>
834
+ </DrawerHeader>
835
+ <DrawerContent>
836
+ <List data-testid="performance-list">
837
+ {items.map((item) => (
838
+ <ListItemButton key={item.id} data-testid={`perf-item-${item.id}`}>
839
+ <ListItemIcon>{item.icon}</ListItemIcon>
840
+ <ListItemText primary={item.label} />
841
+ </ListItemButton>
842
+ ))}
843
+ </List>
844
+ </DrawerContent>
845
+ </Drawer>
846
+ </Box>
847
+ );
848
+ };
849
+
850
+ return <PerformanceComponent />;
851
+ },
852
+ play: async ({ canvasElement }) => {
853
+ const canvas = within(canvasElement);
854
+
855
+ // Wait for performance drawer to render
856
+ await waitFor(
857
+ () => {
858
+ const backdrop = document.querySelector('.MuiBackdrop-root');
859
+ expect(backdrop).toBeInTheDocument();
860
+ },
861
+ { timeout: 5000 },
862
+ );
863
+
864
+ // Test initial render performance (look in document since MUI renders in portal)
865
+ const performanceDrawer = document.querySelector('[data-testid="performance-drawer"]');
866
+ expect(performanceDrawer).toBeInTheDocument();
867
+
868
+ const performanceList = document.querySelector('[data-testid="performance-list"]');
869
+ expect(performanceList).toBeInTheDocument();
870
+
871
+ // Test that initial items are rendered
872
+ const firstItem = document.querySelector('[data-testid="perf-item-0"]');
873
+ const lastItem = document.querySelector('[data-testid="perf-item-49"]');
874
+ expect(firstItem).toBeInTheDocument();
875
+ expect(lastItem).toBeInTheDocument();
876
+
877
+ // Test performance with more items
878
+ const button100 = canvas.getByTestId('perf-100-items');
879
+ await userEvent.click(button100);
880
+
881
+ await waitFor(() => {
882
+ const title = performanceDrawer.querySelector('h6');
883
+ expect(title).toBeInTheDocument();
884
+ expect(title).toHaveTextContent('Performance Test (100 items)');
885
+ });
886
+
887
+ // Verify new items are rendered
888
+ await waitFor(() => {
889
+ const item99 = document.querySelector('[data-testid="perf-item-99"]');
890
+ expect(item99).toBeInTheDocument();
891
+ });
892
+
893
+ // Test scrolling performance
894
+ const scrollableContent = performanceList.parentElement;
895
+ if (scrollableContent) {
896
+ scrollableContent.scrollTop = 1000;
897
+ expect(scrollableContent.scrollTop).toBeGreaterThan(0);
898
+ }
899
+ },
900
+ };
901
+
902
+ // Edge Cases Tests
903
+ export const EdgeCases: Story = {
904
+ name: '🧩 Edge Cases',
905
+ render: () => {
906
+ const EdgeCasesComponent = () => {
907
+ const [states, setStates] = useState({
908
+ empty: true,
909
+ noHeader: false,
910
+ longContent: false,
911
+ persistent: false,
912
+ });
913
+
914
+ const toggleState = (state: keyof typeof states) => {
915
+ setStates((prev) => ({ ...prev, [state]: !prev[state] }));
916
+ };
917
+
918
+ const longText =
919
+ 'This is a very long text content that should test how the drawer handles overflow content. '.repeat(
920
+ 20,
921
+ );
922
+
923
+ return (
924
+ <Box sx={{ height: '100vh', position: 'relative' }}>
925
+ <Stack
926
+ direction="row"
927
+ spacing={1}
928
+ sx={{ p: 1, zIndex: 1300, position: 'relative', flexWrap: 'wrap' }}
929
+ >
930
+ <Button
931
+ size="small"
932
+ onClick={() => toggleState('noHeader')}
933
+ data-testid="edge-no-header"
934
+ >
935
+ No Header
936
+ </Button>
937
+ <Button
938
+ size="small"
939
+ onClick={() => toggleState('longContent')}
940
+ data-testid="edge-long-content"
941
+ >
942
+ Long Content
943
+ </Button>
944
+ <Button
945
+ size="small"
946
+ onClick={() => toggleState('persistent')}
947
+ data-testid="edge-persistent"
948
+ >
949
+ Persistent
950
+ </Button>
951
+ </Stack>
952
+
953
+ {/* Empty Drawer */}
954
+ <Drawer
955
+ open={states.empty}
956
+ onClose={() => toggleState('empty')}
957
+ data-testid="edge-empty-drawer"
958
+ >
959
+ <DrawerHeader onClose={() => toggleState('empty')}>
960
+ <Typography variant="h6">Empty Drawer</Typography>
961
+ </DrawerHeader>
962
+ <DrawerContent>{/* Intentionally empty content */}</DrawerContent>
963
+ </Drawer>
964
+
965
+ {/* No Header Drawer */}
966
+ <Drawer
967
+ open={states.noHeader}
968
+ onClose={() => toggleState('noHeader')}
969
+ data-testid="edge-no-header-drawer"
970
+ >
971
+ <DrawerContent>
972
+ <Box sx={{ p: 2 }}>
973
+ <Typography variant="h6">No Header</Typography>
974
+ <Typography variant="body2">This drawer has no header component.</Typography>
975
+ </Box>
976
+ </DrawerContent>
977
+ </Drawer>
978
+
979
+ {/* Long Content Drawer */}
980
+ <Drawer
981
+ open={states.longContent}
982
+ onClose={() => toggleState('longContent')}
983
+ data-testid="edge-long-content-drawer"
984
+ >
985
+ <DrawerHeader onClose={() => toggleState('longContent')}>
986
+ <Typography variant="h6">Long Content</Typography>
987
+ </DrawerHeader>
988
+ <DrawerContent>
989
+ <Typography variant="body2" data-testid="edge-long-text">
990
+ {longText}
991
+ </Typography>
992
+ </DrawerContent>
993
+ </Drawer>
994
+
995
+ {/* Persistent Drawer */}
996
+ <Drawer
997
+ open={states.persistent}
998
+ onClose={() => toggleState('persistent')}
999
+ data-testid="edge-persistent-drawer"
1000
+ persistent={true}
1001
+ >
1002
+ <DrawerHeader>
1003
+ <Typography variant="h6">Persistent Drawer</Typography>
1004
+ </DrawerHeader>
1005
+ <DrawerContent>
1006
+ <Typography variant="body2">
1007
+ This is a persistent drawer without backdrop click-to-close.
1008
+ </Typography>
1009
+ <Button
1010
+ onClick={() => toggleState('persistent')}
1011
+ data-testid="edge-persistent-close"
1012
+ sx={{ mt: 2 }}
1013
+ >
1014
+ Close Manually
1015
+ </Button>
1016
+ </DrawerContent>
1017
+ </Drawer>
1018
+ </Box>
1019
+ );
1020
+ };
1021
+
1022
+ return <EdgeCasesComponent />;
1023
+ },
1024
+ play: async ({ canvasElement }) => {
1025
+ const canvas = within(canvasElement);
1026
+
1027
+ // Wait for empty drawer to render
1028
+ await waitFor(
1029
+ () => {
1030
+ const backdrop = document.querySelector('.MuiBackdrop-root');
1031
+ expect(backdrop).toBeInTheDocument();
1032
+ },
1033
+ { timeout: 5000 },
1034
+ );
1035
+
1036
+ // Test empty drawer (look in document since MUI renders in portal)
1037
+ const emptyDrawer = document.querySelector('[data-testid="edge-empty-drawer"]');
1038
+ expect(emptyDrawer).toBeInTheDocument();
1039
+
1040
+ await waitFor(() => {
1041
+ const emptyTitle = emptyDrawer.querySelector('h6');
1042
+ expect(emptyTitle).toBeInTheDocument();
1043
+ expect(emptyTitle).toHaveTextContent('Empty Drawer');
1044
+ });
1045
+
1046
+ // Test no header drawer
1047
+ const noHeaderButton = canvas.getByTestId('edge-no-header');
1048
+ await userEvent.click(noHeaderButton);
1049
+
1050
+ await waitFor(() => {
1051
+ const noHeaderDrawer = document.querySelector('[data-testid="edge-no-header-drawer"]');
1052
+ expect(noHeaderDrawer).toBeInTheDocument();
1053
+ const noHeaderText = Array.from(document.querySelectorAll('*')).find(
1054
+ (el) => el.textContent === 'No Header',
1055
+ );
1056
+ expect(noHeaderText).toBeInTheDocument();
1057
+ });
1058
+
1059
+ // Test long content drawer
1060
+ const longContentButton = canvas.getByTestId('edge-long-content');
1061
+ await userEvent.click(longContentButton);
1062
+
1063
+ await waitFor(() => {
1064
+ const longContentDrawer = document.querySelector('[data-testid="edge-long-content-drawer"]');
1065
+ expect(longContentDrawer).toBeInTheDocument();
1066
+ const longText = document.querySelector('[data-testid="edge-long-text"]');
1067
+ expect(longText).toBeInTheDocument();
1068
+ expect(longText.textContent?.length).toBeGreaterThan(100);
1069
+ });
1070
+
1071
+ // Test persistent drawer
1072
+ const persistentButton = canvas.getByTestId('edge-persistent');
1073
+ await userEvent.click(persistentButton);
1074
+
1075
+ await waitFor(() => {
1076
+ const persistentDrawer = document.querySelector('[data-testid="edge-persistent-drawer"]');
1077
+ expect(persistentDrawer).toBeInTheDocument();
1078
+ const persistentTitle = persistentDrawer.querySelector('h6');
1079
+ expect(persistentTitle).toBeInTheDocument();
1080
+ expect(persistentTitle).toHaveTextContent('Persistent Drawer');
1081
+ });
1082
+
1083
+ // Test manual close for persistent drawer
1084
+ const manualCloseButton = canvas.getByTestId('edge-persistent-close');
1085
+ await userEvent.click(manualCloseButton);
1086
+
1087
+ await waitFor(() => {
1088
+ const persistentDrawer = document.querySelector('[data-testid="edge-persistent-drawer"]');
1089
+ // For persistent drawers, check if it's hidden rather than removed from DOM
1090
+ if (persistentDrawer) {
1091
+ const drawerPaper = persistentDrawer.querySelector('.MuiDrawer-paper');
1092
+ const isHidden =
1093
+ drawerPaper &&
1094
+ (drawerPaper.style.visibility === 'hidden' ||
1095
+ drawerPaper.style.transform.includes('translateX(-'));
1096
+ expect(isHidden).toBe(true);
1097
+ } else {
1098
+ expect(persistentDrawer).not.toBeInTheDocument();
1099
+ }
1100
+ });
1101
+ },
1102
+ };
1103
+
1104
+ // Integration Tests
1105
+ export const Integration: Story = {
1106
+ name: '🔗 Integration',
1107
+ render: () => {
1108
+ const IntegrationComponent = () => {
1109
+ const [drawerOpen, setDrawerOpen] = useState(false);
1110
+ const [selectedPage, setSelectedPage] = useState('home');
1111
+ const [notifications, setNotifications] = useState(3);
1112
+
1113
+ const handleNavigation = (page: string) => {
1114
+ setSelectedPage(page);
1115
+ if (page === 'notifications') {
1116
+ setNotifications(0);
1117
+ }
1118
+ };
1119
+
1120
+ return (
1121
+ <Box sx={{ display: 'flex', height: '100vh' }}>
1122
+ {/* Main Drawer */}
1123
+ <Drawer
1124
+ open={drawerOpen}
1125
+ onClose={() => setDrawerOpen(false)}
1126
+ data-testid="integration-main-drawer"
1127
+ persistent={false}
1128
+ >
1129
+ <DrawerHeader onClose={() => setDrawerOpen(false)}>
1130
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
1131
+ <Box
1132
+ sx={{
1133
+ width: 32,
1134
+ height: 32,
1135
+ borderRadius: '50%',
1136
+ bgcolor: 'primary.main',
1137
+ display: 'flex',
1138
+ alignItems: 'center',
1139
+ justifyContent: 'center',
1140
+ color: 'white',
1141
+ fontSize: '0.875rem',
1142
+ fontWeight: 'bold',
1143
+ }}
1144
+ >
1145
+ A
1146
+ </Box>
1147
+ <Typography variant="h6">App Name</Typography>
1148
+ </Box>
1149
+ </DrawerHeader>
1150
+ <DrawerContent>
1151
+ <List>
1152
+ <ListItemButton
1153
+ selected={selectedPage === 'home'}
1154
+ onClick={() => handleNavigation('home')}
1155
+ data-testid="integration-nav-home"
1156
+ >
1157
+ <ListItemIcon>
1158
+ <Home />
1159
+ </ListItemIcon>
1160
+ <ListItemText primary="Home" />
1161
+ </ListItemButton>
1162
+ <ListItemButton
1163
+ selected={selectedPage === 'dashboard'}
1164
+ onClick={() => handleNavigation('dashboard')}
1165
+ data-testid="integration-nav-dashboard"
1166
+ >
1167
+ <ListItemIcon>
1168
+ <Dashboard />
1169
+ </ListItemIcon>
1170
+ <ListItemText primary="Dashboard" />
1171
+ </ListItemButton>
1172
+ <ListItemButton
1173
+ selected={selectedPage === 'notifications'}
1174
+ onClick={() => handleNavigation('notifications')}
1175
+ data-testid="integration-nav-notifications"
1176
+ >
1177
+ <ListItemIcon>
1178
+ <Box sx={{ position: 'relative' }}>
1179
+ <Settings />
1180
+ {notifications > 0 && (
1181
+ <Box
1182
+ sx={{
1183
+ position: 'absolute',
1184
+ top: -4,
1185
+ right: -4,
1186
+ width: 16,
1187
+ height: 16,
1188
+ borderRadius: '50%',
1189
+ bgcolor: 'error.main',
1190
+ color: 'white',
1191
+ display: 'flex',
1192
+ alignItems: 'center',
1193
+ justifyContent: 'center',
1194
+ fontSize: '0.75rem',
1195
+ }}
1196
+ >
1197
+ {notifications}
1198
+ </Box>
1199
+ )}
1200
+ </Box>
1201
+ </ListItemIcon>
1202
+ <ListItemText
1203
+ primary="Notifications"
1204
+ secondary={notifications > 0 ? `${notifications} new` : 'No new notifications'}
1205
+ />
1206
+ </ListItemButton>
1207
+ </List>
1208
+ </DrawerContent>
1209
+ </Drawer>
1210
+
1211
+ {/* Main Content Area */}
1212
+ <Box component="main" sx={{ flexGrow: 1, display: 'flex', flexDirection: 'column' }}>
1213
+ {/* App Bar */}
1214
+ <Box
1215
+ sx={{
1216
+ p: 2,
1217
+ borderBottom: 1,
1218
+ borderColor: 'divider',
1219
+ display: 'flex',
1220
+ alignItems: 'center',
1221
+ gap: 2,
1222
+ }}
1223
+ >
1224
+ <IconButton
1225
+ onClick={() => setDrawerOpen(!drawerOpen)}
1226
+ data-testid="integration-menu-button"
1227
+ >
1228
+ <MenuIcon />
1229
+ </IconButton>
1230
+ <Typography variant="h6" sx={{ flexGrow: 1 }}>
1231
+ {selectedPage.charAt(0).toUpperCase() + selectedPage.slice(1)}
1232
+ </Typography>
1233
+ {notifications > 0 && (
1234
+ <Box
1235
+ sx={{
1236
+ bgcolor: 'error.main',
1237
+ color: 'white',
1238
+ borderRadius: 1,
1239
+ px: 1,
1240
+ py: 0.5,
1241
+ fontSize: '0.75rem',
1242
+ }}
1243
+ >
1244
+ {notifications} notifications
1245
+ </Box>
1246
+ )}
1247
+ </Box>
1248
+
1249
+ {/* Page Content */}
1250
+ <Box sx={{ p: 3, flex: 1 }} data-testid="integration-main-content">
1251
+ <Typography variant="h4" gutterBottom>
1252
+ {selectedPage === 'home' && 'Welcome Home'}
1253
+ {selectedPage === 'dashboard' && 'Dashboard Overview'}
1254
+ {selectedPage === 'notifications' && 'Notification Center'}
1255
+ </Typography>
1256
+ <Typography variant="body1">
1257
+ This is the {selectedPage} page content. The drawer integrates with the main
1258
+ application navigation and state management.
1259
+ </Typography>
1260
+ {selectedPage === 'notifications' && (
1261
+ <Typography variant="body2" sx={{ mt: 2, fontStyle: 'italic' }}>
1262
+ All notifications have been marked as read.
1263
+ </Typography>
1264
+ )}
1265
+ </Box>
1266
+ </Box>
1267
+ </Box>
1268
+ );
1269
+ };
1270
+
1271
+ return <IntegrationComponent />;
1272
+ },
1273
+ play: async ({ canvasElement }) => {
1274
+ const canvas = within(canvasElement);
1275
+
1276
+ // Test initial state
1277
+ expect(canvas.getByText('Welcome Home')).toBeInTheDocument();
1278
+
1279
+ // Test drawer opening
1280
+ const menuButton = canvas.getByTestId('integration-menu-button');
1281
+ await userEvent.click(menuButton);
1282
+
1283
+ await waitFor(() => {
1284
+ const drawer = document.querySelector('[data-testid="integration-main-drawer"]');
1285
+ expect(drawer).toBeInTheDocument();
1286
+ const appName = Array.from(document.querySelectorAll('*')).find(
1287
+ (el) => el.textContent === 'App Name',
1288
+ );
1289
+ expect(appName).toBeInTheDocument();
1290
+ });
1291
+
1292
+ // Test navigation to dashboard
1293
+ const dashboardItem = document.querySelector('[data-testid="integration-nav-dashboard"]');
1294
+ await userEvent.click(dashboardItem);
1295
+
1296
+ await waitFor(() => {
1297
+ const dashboardOverview = canvas.getByText('Dashboard Overview');
1298
+ expect(dashboardOverview).toBeInTheDocument();
1299
+ });
1300
+
1301
+ // Test notification badge functionality
1302
+ const notificationsItem = document.querySelector(
1303
+ '[data-testid="integration-nav-notifications"]',
1304
+ );
1305
+
1306
+ // Should show notification badge
1307
+ const notificationBadge = Array.from(document.querySelectorAll('*')).find(
1308
+ (el) => el.textContent === '3',
1309
+ );
1310
+ expect(notificationBadge).toBeInTheDocument();
1311
+
1312
+ await userEvent.click(notificationsItem);
1313
+
1314
+ await waitFor(() => {
1315
+ const notificationCenter = canvas.getByText('Notification Center');
1316
+ expect(notificationCenter).toBeInTheDocument();
1317
+ const notificationMessage = canvas.getByText('All notifications have been marked as read.');
1318
+ expect(notificationMessage).toBeInTheDocument();
1319
+ });
1320
+
1321
+ // Notification badge should be cleared
1322
+ await waitFor(() => {
1323
+ const notificationText = canvas.queryByText('3 notifications');
1324
+ expect(notificationText).not.toBeInTheDocument();
1325
+ });
1326
+
1327
+ // Test drawer closing
1328
+ const closeButton = document.querySelector('button[aria-label*="close" i]');
1329
+ await userEvent.click(closeButton);
1330
+
1331
+ await waitFor(() => {
1332
+ const appName = Array.from(document.querySelectorAll('*')).find(
1333
+ (el) => el.textContent === 'App Name',
1334
+ );
1335
+ // appName should be undefined (not found) when drawer is closed
1336
+ expect(appName).toBeUndefined();
1337
+ });
1338
+ },
1339
+ };