@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,1168 @@
1
+ import { Button, List, ListItem, ListItemText,Stack, Typography } from '@mui/material';
2
+ import type { Meta, StoryObj } from '@storybook/react-vite';
3
+ import React from 'react';
4
+ import { expect, fn,userEvent, waitFor, within } from 'storybook/test';
5
+
6
+ import { Popover } from './Popover';
7
+
8
+ const meta: Meta<typeof Popover> = {
9
+ title: 'DataDisplay/Popover/Tests',
10
+ component: Popover,
11
+ parameters: {
12
+ layout: 'centered',
13
+ chromatic: { disableSnapshot: false },
14
+ },
15
+ tags: ['autodocs', 'test', 'component:Popover'],
16
+ };
17
+ export default meta;
18
+ export type Story = StoryObj<typeof meta>;
19
+
20
+ // Helper function to get popover elements from document (since MUI renders in portal)
21
+ const getPopoverElement = (testId: string) => document.querySelector(`[data-testid="${testId}"]`);
22
+ const queryPopoverElement = (testId: string) => document.querySelector(`[data-testid="${testId}"]`);
23
+
24
+ // Helper component for tests
25
+ const PopoverTestWrapper = ({
26
+ children,
27
+ onOpen = fn(),
28
+ onClose = fn(),
29
+ ...props
30
+ }: {
31
+ children?: React.ReactNode;
32
+ onOpen?: () => void;
33
+ onClose?: () => void;
34
+ variant?: 'default' | 'glass' | 'arrow';
35
+ glow?: boolean;
36
+ pulse?: boolean;
37
+ maxWidth?: number;
38
+ }) => {
39
+ const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null);
40
+ const open = Boolean(anchorEl);
41
+
42
+ const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
43
+ setAnchorEl(event.currentTarget);
44
+ onOpen();
45
+ };
46
+
47
+ const handleClose = () => {
48
+ setAnchorEl(null);
49
+ onClose();
50
+ };
51
+
52
+ return (
53
+ <>
54
+ <Button variant="contained" onClick={handleClick} data-testid="popover-trigger">
55
+ Open Popover
56
+ </Button>
57
+ <Popover
58
+ open={open}
59
+ anchorEl={anchorEl}
60
+ onClose={handleClose}
61
+ anchorOrigin={{
62
+ vertical: 'bottom',
63
+ horizontal: 'left',
64
+ }}
65
+ data-testid="popover"
66
+ {...props}
67
+ >
68
+ {children}
69
+ </Popover>
70
+ </>
71
+ );
72
+ };
73
+
74
+ // 1. Basic Interaction Tests
75
+ export const BasicInteraction: Story = {
76
+ render: () => (
77
+ <>
78
+ <PopoverTestWrapper>
79
+ <Typography sx={{ p: 2 }} data-testid="popover-content">
80
+ This is basic popover content.
81
+ </Typography>
82
+ </PopoverTestWrapper>
83
+ <div aria-label="Status of the test run" style={{ marginTop: 20 }}>
84
+ PASS
85
+ </div>
86
+ </>
87
+ ),
88
+ play: async ({ canvasElement, step }) => {
89
+ const canvas = within(canvasElement);
90
+ const statusElement = canvas.getByLabelText('Status of the test run');
91
+ statusElement.textContent = 'RUNS';
92
+
93
+ await step('Initial state should be closed', async () => {
94
+ const trigger = canvas.getByTestId('popover-trigger');
95
+ expect(trigger).toBeInTheDocument();
96
+
97
+ // Popover should not be visible initially
98
+ expect(document.querySelector('[data-testid="popover-content"]')).not.toBeInTheDocument();
99
+ });
100
+
101
+ await step('Should open popover on trigger click', async () => {
102
+ const trigger = canvas.getByTestId('popover-trigger');
103
+ await userEvent.click(trigger);
104
+
105
+ await waitFor(() => {
106
+ // MUI Popover renders content in a portal (document body), not in canvas
107
+ const content = document.querySelector('[data-testid="popover-content"]');
108
+ expect(content).toBeInTheDocument();
109
+ expect(content).toHaveTextContent('This is basic popover content.');
110
+
111
+ // Verify popover is positioned relative to trigger
112
+ const popoverContainer = document.querySelector('[role="presentation"]');
113
+ expect(popoverContainer).toBeInTheDocument();
114
+
115
+ // Test that popover Paper element exists with proper styling
116
+ const paper = document.querySelector('.MuiPaper-root');
117
+ expect(paper).toBeInTheDocument();
118
+ });
119
+ });
120
+
121
+ await step('Should close popover on outside click', async () => {
122
+ // Click outside the popover (on backdrop)
123
+ const backdrop = document.querySelector('.MuiBackdrop-root');
124
+ if (backdrop) {
125
+ await userEvent.click(backdrop as HTMLElement);
126
+ } else {
127
+ await userEvent.click(canvasElement);
128
+ }
129
+
130
+ await waitFor(() => {
131
+ expect(document.querySelector('[data-testid="popover-content"]')).not.toBeInTheDocument();
132
+ });
133
+ });
134
+
135
+ // Mark test as passed
136
+ statusElement.textContent = 'PASS';
137
+ },
138
+ };
139
+
140
+ // 2. Form Interaction Tests
141
+ export const FormInteraction: Story = {
142
+ render: () => {
143
+ const [clickedItem, setClickedItem] = React.useState('');
144
+ return (
145
+ <>
146
+ <PopoverTestWrapper>
147
+ <div style={{ padding: 16 }}>
148
+ <Typography variant="h6" gutterBottom>
149
+ User Menu
150
+ </Typography>
151
+ <List dense>
152
+ <ListItem
153
+ component="button"
154
+ data-testid="menu-item-profile"
155
+ onClick={() => setClickedItem('profile')}
156
+ >
157
+ <ListItemText primary="Profile Settings" />
158
+ </ListItem>
159
+ <ListItem
160
+ component="button"
161
+ data-testid="menu-item-account"
162
+ onClick={() => setClickedItem('account')}
163
+ >
164
+ <ListItemText primary="Account Security" />
165
+ </ListItem>
166
+ <ListItem
167
+ component="button"
168
+ data-testid="menu-item-notifications"
169
+ onClick={() => setClickedItem('notifications')}
170
+ >
171
+ <ListItemText primary="Notifications" />
172
+ </ListItem>
173
+ </List>
174
+ </div>
175
+ </PopoverTestWrapper>
176
+ <div data-testid="clicked-item" style={{ display: 'none' }}>
177
+ {clickedItem}
178
+ </div>
179
+ <div aria-label="Status of the test run" style={{ marginTop: 20 }}>
180
+ PASS
181
+ </div>
182
+ </>
183
+ );
184
+ },
185
+ play: async ({ canvasElement, step }) => {
186
+ const canvas = within(canvasElement);
187
+ const statusElement = canvas.getByLabelText('Status of the test run');
188
+ statusElement.textContent = 'RUNS';
189
+
190
+ await step('Should open popover with menu items', async () => {
191
+ const trigger = canvas.getByTestId('popover-trigger');
192
+ await userEvent.click(trigger);
193
+
194
+ await waitFor(() => {
195
+ const profileItem = getPopoverElement('menu-item-profile');
196
+ const accountItem = getPopoverElement('menu-item-account');
197
+ const notificationsItem = getPopoverElement('menu-item-notifications');
198
+
199
+ expect(profileItem).toBeInTheDocument();
200
+ expect(accountItem).toBeInTheDocument();
201
+ expect(notificationsItem).toBeInTheDocument();
202
+
203
+ // Verify menu items have proper text content
204
+ expect(profileItem).toHaveTextContent('Profile Settings');
205
+ expect(accountItem).toHaveTextContent('Account Security');
206
+ expect(notificationsItem).toHaveTextContent('Notifications');
207
+ });
208
+ });
209
+
210
+ await step('Should be able to click menu items and trigger actions', async () => {
211
+ const profileItem = getPopoverElement('menu-item-profile') as HTMLElement;
212
+ await userEvent.click(profileItem);
213
+
214
+ // Verify click handler was called
215
+ await waitFor(() => {
216
+ const clickedItemElement = canvas.getByTestId('clicked-item');
217
+ expect(clickedItemElement).toHaveTextContent('profile');
218
+ });
219
+
220
+ // Menu item should still be accessible after click
221
+ expect(profileItem).toBeInTheDocument();
222
+
223
+ // Test clicking another item
224
+ const accountItem = getPopoverElement('menu-item-account') as HTMLElement;
225
+ await userEvent.click(accountItem);
226
+
227
+ await waitFor(() => {
228
+ const clickedItemElement = canvas.getByTestId('clicked-item');
229
+ expect(clickedItemElement).toHaveTextContent('account');
230
+ });
231
+ });
232
+
233
+ statusElement.textContent = 'PASS';
234
+ },
235
+ };
236
+
237
+ // 3. Keyboard Navigation Tests
238
+ export const KeyboardNavigation: Story = {
239
+ render: () => (
240
+ <>
241
+ <PopoverTestWrapper>
242
+ <div style={{ padding: 16 }}>
243
+ <Typography variant="h6" gutterBottom>
244
+ Keyboard Navigation Test
245
+ </Typography>
246
+ <List dense>
247
+ <ListItem component="button" tabIndex={0} data-testid="item-1">
248
+ <ListItemText primary="First Item" />
249
+ </ListItem>
250
+ <ListItem component="button" tabIndex={0} data-testid="item-2">
251
+ <ListItemText primary="Second Item" />
252
+ </ListItem>
253
+ <ListItem component="button" tabIndex={0} data-testid="item-3">
254
+ <ListItemText primary="Third Item" />
255
+ </ListItem>
256
+ </List>
257
+ </div>
258
+ </PopoverTestWrapper>
259
+ <div aria-label="Status of the test run" style={{ marginTop: 20 }}>
260
+ PASS
261
+ </div>
262
+ </>
263
+ ),
264
+ play: async ({ canvasElement, step }) => {
265
+ const canvas = within(canvasElement);
266
+ const statusElement = canvas.getByLabelText('Status of the test run');
267
+ statusElement.textContent = 'RUNS';
268
+
269
+ await step('Should open popover with Enter key', async () => {
270
+ const trigger = canvas.getByTestId('popover-trigger');
271
+ trigger.focus();
272
+ expect(trigger).toHaveFocus();
273
+
274
+ await userEvent.keyboard('{Enter}');
275
+
276
+ await waitFor(() => {
277
+ const firstItem = getPopoverElement('item-1');
278
+ expect(firstItem).toBeInTheDocument();
279
+
280
+ // Verify all items are present and focusable
281
+ const secondItem = getPopoverElement('item-2');
282
+ const thirdItem = getPopoverElement('item-3');
283
+ expect(secondItem).toBeInTheDocument();
284
+ expect(thirdItem).toBeInTheDocument();
285
+
286
+ // Verify items have proper tabIndex for keyboard navigation
287
+ expect(firstItem).toHaveAttribute('tabIndex', '0');
288
+ expect(secondItem).toHaveAttribute('tabIndex', '0');
289
+ expect(thirdItem).toHaveAttribute('tabIndex', '0');
290
+ });
291
+ });
292
+
293
+ await step('Should navigate between items with Tab key', async () => {
294
+ // Tab through items
295
+ const firstItem = getPopoverElement('item-1') as HTMLElement;
296
+ firstItem.focus();
297
+ expect(firstItem).toHaveFocus();
298
+
299
+ await userEvent.keyboard('{Tab}');
300
+ const secondItem = getPopoverElement('item-2') as HTMLElement;
301
+ expect(secondItem).toHaveFocus();
302
+
303
+ await userEvent.keyboard('{Tab}');
304
+ const thirdItem = getPopoverElement('item-3') as HTMLElement;
305
+ expect(thirdItem).toHaveFocus();
306
+ });
307
+
308
+ await step('Should close popover with Escape key', async () => {
309
+ await userEvent.keyboard('{Escape}');
310
+
311
+ await waitFor(() => {
312
+ expect(queryPopoverElement('item-1')).not.toBeInTheDocument();
313
+ expect(queryPopoverElement('item-2')).not.toBeInTheDocument();
314
+ expect(queryPopoverElement('item-3')).not.toBeInTheDocument();
315
+
316
+ // Verify focus returns to trigger
317
+ const trigger = canvas.getByTestId('popover-trigger');
318
+ expect(trigger).toHaveFocus();
319
+ });
320
+ });
321
+
322
+ statusElement.textContent = 'PASS';
323
+ },
324
+ };
325
+
326
+ // 4. Screen Reader Tests
327
+ export const ScreenReader: Story = {
328
+ render: () => (
329
+ <>
330
+ <PopoverTestWrapper>
331
+ <div
332
+ role="dialog"
333
+ aria-label="User menu popover"
334
+ aria-describedby="popover-desc"
335
+ style={{ padding: 16 }}
336
+ >
337
+ <Typography variant="h6" gutterBottom id="popover-title">
338
+ Accessible Menu
339
+ </Typography>
340
+ <Typography variant="body2" id="popover-desc" sx={{ mb: 1 }}>
341
+ Navigate menu options using arrow keys
342
+ </Typography>
343
+ <List dense aria-labelledby="popover-title">
344
+ <ListItem
345
+ component="button"
346
+ role="menuitem"
347
+ data-testid="accessible-item-1"
348
+ aria-label="Navigate to profile settings"
349
+ >
350
+ <ListItemText primary="Accessible Item 1" />
351
+ </ListItem>
352
+ <ListItem
353
+ component="button"
354
+ role="menuitem"
355
+ data-testid="accessible-item-2"
356
+ aria-label="Navigate to account settings"
357
+ >
358
+ <ListItemText primary="Accessible Item 2" />
359
+ </ListItem>
360
+ </List>
361
+ </div>
362
+ </PopoverTestWrapper>
363
+ <div aria-label="Status of the test run" style={{ marginTop: 20 }}>
364
+ PASS
365
+ </div>
366
+ </>
367
+ ),
368
+ play: async ({ canvasElement, step }) => {
369
+ const canvas = within(canvasElement);
370
+ const statusElement = canvas.getByLabelText('Status of the test run');
371
+ statusElement.textContent = 'RUNS';
372
+
373
+ await step('Should have proper ARIA attributes for screen readers', async () => {
374
+ const trigger = canvas.getByTestId('popover-trigger');
375
+ await userEvent.click(trigger);
376
+
377
+ await waitFor(() => {
378
+ // Use document queries for portal-rendered content
379
+ const dialog = document.querySelector('[role="dialog"]');
380
+ expect(dialog).toBeInTheDocument();
381
+ expect(dialog).toHaveAttribute('aria-label', 'User menu popover');
382
+ expect(dialog).toHaveAttribute('aria-describedby', 'popover-desc');
383
+
384
+ // Verify menu items have proper roles and labels
385
+ const menuItems = document.querySelectorAll('[role="menuitem"]');
386
+ expect(menuItems).toHaveLength(2);
387
+ expect(menuItems[0]).toHaveAttribute('aria-label', 'Navigate to profile settings');
388
+ expect(menuItems[1]).toHaveAttribute('aria-label', 'Navigate to account settings');
389
+ });
390
+ });
391
+
392
+ await step('Should have proper heading structure for screen readers', async () => {
393
+ // Use document queries for portal-rendered content
394
+ const title = document.querySelector('#popover-title');
395
+ expect(title).toBeInTheDocument();
396
+ expect(title).toHaveTextContent('Accessible Menu');
397
+
398
+ const description = document.querySelector('#popover-desc');
399
+ expect(description).toBeInTheDocument();
400
+ expect(description).toHaveTextContent('Navigate menu options using arrow keys');
401
+
402
+ const list = document.querySelector('[aria-labelledby="popover-title"]');
403
+ expect(list).toBeInTheDocument();
404
+
405
+ // Verify MUI Popover backdrop has proper role
406
+ const backdrop = document.querySelector('.MuiBackdrop-root');
407
+ if (backdrop) {
408
+ expect(backdrop).toHaveAttribute('aria-hidden', 'true');
409
+ }
410
+ });
411
+
412
+ statusElement.textContent = 'PASS';
413
+ },
414
+ };
415
+
416
+ // 5. Focus Management Tests
417
+ export const FocusManagement: Story = {
418
+ render: () => (
419
+ <>
420
+ <div>
421
+ <Button data-testid="before-popover">Before Popover</Button>
422
+ <PopoverTestWrapper>
423
+ <div style={{ padding: 16 }}>
424
+ <Button data-testid="first-focusable" autoFocus>
425
+ First Focusable
426
+ </Button>
427
+ <Button data-testid="second-focusable">Second Focusable</Button>
428
+ <Button data-testid="third-focusable">Third Focusable</Button>
429
+ </div>
430
+ </PopoverTestWrapper>
431
+ <Button data-testid="after-popover">After Popover</Button>
432
+ </div>
433
+ <div aria-label="Status of the test run" style={{ marginTop: 20 }}>
434
+ PASS
435
+ </div>
436
+ </>
437
+ ),
438
+ play: async ({ canvasElement, step }) => {
439
+ const canvas = within(canvasElement);
440
+ const statusElement = canvas.getByLabelText('Status of the test run');
441
+ statusElement.textContent = 'RUNS';
442
+
443
+ await step('Should manage focus when popover opens', async () => {
444
+ const trigger = canvas.getByTestId('popover-trigger');
445
+
446
+ // Set initial focus to before button
447
+ const beforeButton = canvas.getByTestId('before-popover');
448
+ beforeButton.focus();
449
+ expect(beforeButton).toHaveFocus();
450
+
451
+ // Open popover
452
+ await userEvent.click(trigger);
453
+
454
+ await waitFor(() => {
455
+ // Use document queries for portal-rendered content
456
+ const firstFocusable = document.querySelector('[data-testid="first-focusable"]');
457
+ expect(firstFocusable).toBeInTheDocument();
458
+
459
+ // Verify autoFocus worked
460
+ expect(firstFocusable).toHaveFocus();
461
+
462
+ // Verify all focusable elements are present
463
+ const secondFocusable = document.querySelector('[data-testid="second-focusable"]');
464
+ const thirdFocusable = document.querySelector('[data-testid="third-focusable"]');
465
+ expect(secondFocusable).toBeInTheDocument();
466
+ expect(thirdFocusable).toBeInTheDocument();
467
+ });
468
+ });
469
+
470
+ await step('Should cycle focus within popover', async () => {
471
+ // Tab through elements (use document queries for portal content)
472
+ await userEvent.keyboard('{Tab}');
473
+ const secondFocusable = document.querySelector('[data-testid="second-focusable"]');
474
+ expect(secondFocusable).toHaveFocus();
475
+
476
+ await userEvent.keyboard('{Tab}');
477
+ const thirdFocusable = document.querySelector('[data-testid="third-focusable"]');
478
+ expect(thirdFocusable).toHaveFocus();
479
+
480
+ // Shift+Tab to go back
481
+ await userEvent.keyboard('{Shift>}{Tab}{/Shift}');
482
+ expect(secondFocusable).toHaveFocus();
483
+ });
484
+
485
+ await step('Should return focus to trigger when closed', async () => {
486
+ await userEvent.keyboard('{Escape}');
487
+
488
+ await waitFor(() => {
489
+ const trigger = canvas.getByTestId('popover-trigger');
490
+ expect(trigger).toHaveFocus();
491
+
492
+ // Verify popover content is removed (check in document, not canvas)
493
+ expect(document.querySelector('[data-testid="first-focusable"]')).not.toBeInTheDocument();
494
+ expect(document.querySelector('[data-testid="second-focusable"]')).not.toBeInTheDocument();
495
+ });
496
+ });
497
+
498
+ statusElement.textContent = 'PASS';
499
+ },
500
+ };
501
+
502
+ // 6. Responsive Design Tests
503
+ export const ResponsiveDesign: Story = {
504
+ parameters: {
505
+ viewport: {
506
+ defaultViewport: 'mobile1',
507
+ },
508
+ },
509
+ render: () => (
510
+ <>
511
+ <PopoverTestWrapper maxWidth={280}>
512
+ <div style={{ padding: 16 }}>
513
+ <Typography variant="h6" gutterBottom>
514
+ Mobile Responsive Content
515
+ </Typography>
516
+ <Typography variant="body2" data-testid="mobile-content">
517
+ This content should adapt to mobile viewport sizes and maintain readability.
518
+ </Typography>
519
+ <Button data-testid="mobile-button" size="small" fullWidth>
520
+ Mobile Action
521
+ </Button>
522
+ </div>
523
+ </PopoverTestWrapper>
524
+ <div aria-label="Status of the test run" style={{ marginTop: 20 }}>
525
+ PASS
526
+ </div>
527
+ </>
528
+ ),
529
+ play: async ({ canvasElement, step }) => {
530
+ const canvas = within(canvasElement);
531
+ const statusElement = canvas.getByLabelText('Status of the test run');
532
+ statusElement.textContent = 'RUNS';
533
+
534
+ await step('Should display properly on mobile viewport with constrained width', async () => {
535
+ const trigger = canvas.getByTestId('popover-trigger');
536
+ await userEvent.click(trigger);
537
+
538
+ await waitFor(() => {
539
+ const content = getPopoverElement('mobile-content');
540
+ expect(content).toBeInTheDocument();
541
+ expect(content).toHaveTextContent(
542
+ 'This content should adapt to mobile viewport sizes and maintain readability.',
543
+ );
544
+
545
+ // Verify mobile button is full width
546
+ const mobileButton = getPopoverElement('mobile-button');
547
+ expect(mobileButton).toBeInTheDocument();
548
+ expect(mobileButton).toHaveClass('MuiButton-fullWidth');
549
+
550
+ // Verify popover Paper respects maxWidth
551
+ const paper = document.querySelector('.MuiPaper-root') as HTMLElement;
552
+ if (paper) {
553
+ const computedStyle = window.getComputedStyle(paper);
554
+ const maxWidth = computedStyle.maxWidth;
555
+ expect(maxWidth).toBe('280px');
556
+ }
557
+ });
558
+ });
559
+
560
+ await step('Should position correctly on mobile screens', async () => {
561
+ // Verify popover is visible within viewport
562
+ const popoverRoot = document.querySelector('[role="presentation"]') as HTMLElement;
563
+ if (popoverRoot) {
564
+ const rect = popoverRoot.getBoundingClientRect();
565
+ expect(rect.left).toBeGreaterThanOrEqual(0);
566
+ expect(rect.top).toBeGreaterThanOrEqual(0);
567
+ }
568
+ });
569
+
570
+ statusElement.textContent = 'PASS';
571
+ },
572
+ };
573
+
574
+ // 7. Theme Variations Tests
575
+ export const ThemeVariations: Story = {
576
+ render: () => (
577
+ <>
578
+ <Stack spacing={2} direction="row">
579
+ <PopoverTestWrapper variant="default" data-testid="default-popover">
580
+ <Typography sx={{ p: 2 }} data-testid="default-content">
581
+ Default Theme
582
+ </Typography>
583
+ </PopoverTestWrapper>
584
+ <PopoverTestWrapper variant="glass" data-testid="glass-popover">
585
+ <Typography sx={{ p: 2 }} data-testid="glass-content">
586
+ Glass Theme
587
+ </Typography>
588
+ </PopoverTestWrapper>
589
+ <PopoverTestWrapper variant="arrow" data-testid="arrow-popover">
590
+ <Typography sx={{ p: 2 }} data-testid="arrow-content">
591
+ Arrow Theme
592
+ </Typography>
593
+ </PopoverTestWrapper>
594
+ </Stack>
595
+ <div aria-label="Status of the test run" style={{ marginTop: 20 }}>
596
+ PASS
597
+ </div>
598
+ </>
599
+ ),
600
+ play: async ({ canvasElement, step }) => {
601
+ const canvas = within(canvasElement);
602
+ const statusElement = canvas.getByLabelText('Status of the test run');
603
+ statusElement.textContent = 'RUNS';
604
+
605
+ await step('Should render and style all theme variants correctly', async () => {
606
+ const triggers = canvas.getAllByTestId('popover-trigger');
607
+ expect(triggers).toHaveLength(3);
608
+
609
+ // Test default variant
610
+ await userEvent.click(triggers[0]);
611
+ await waitFor(() => {
612
+ // Use document queries for portal-rendered content
613
+ const content = document.querySelector('[data-testid="default-content"]');
614
+ expect(content).toBeInTheDocument();
615
+ expect(content).toHaveTextContent('Default Theme');
616
+
617
+ // Verify default variant styling
618
+ const paper = content?.closest('.MuiPaper-root') as HTMLElement;
619
+ if (paper) {
620
+ const computedStyle = window.getComputedStyle(paper);
621
+ expect(computedStyle.borderRadius).toBeTruthy();
622
+ expect(computedStyle.backgroundColor).toBeTruthy();
623
+ }
624
+ });
625
+ await userEvent.keyboard('{Escape}');
626
+
627
+ // Wait for animation
628
+ await waitFor(() => {
629
+ expect(document.querySelector('[data-testid="default-content"]')).not.toBeInTheDocument();
630
+ });
631
+
632
+ // Test glass variant
633
+ await userEvent.click(triggers[1]);
634
+ await waitFor(() => {
635
+ // Use document queries for portal-rendered content
636
+ const content = document.querySelector('[data-testid="glass-content"]');
637
+ expect(content).toBeInTheDocument();
638
+ expect(content).toHaveTextContent('Glass Theme');
639
+
640
+ // Verify glass variant has backdrop filter
641
+ const paper = content?.closest('.MuiPaper-root') as HTMLElement;
642
+ if (paper) {
643
+ const computedStyle = window.getComputedStyle(paper);
644
+ // Glass variant should have backdrop-filter
645
+ expect(computedStyle.backdropFilter || computedStyle.webkitBackdropFilter).toBeTruthy();
646
+ }
647
+ });
648
+ await userEvent.keyboard('{Escape}');
649
+
650
+ // Wait for animation
651
+ await waitFor(() => {
652
+ expect(document.querySelector('[data-testid="glass-content"]')).not.toBeInTheDocument();
653
+ });
654
+
655
+ // Test arrow variant
656
+ await userEvent.click(triggers[2]);
657
+ await waitFor(() => {
658
+ // Use document queries for portal-rendered content
659
+ const content = document.querySelector('[data-testid="arrow-content"]');
660
+ expect(content).toBeInTheDocument();
661
+ expect(content).toHaveTextContent('Arrow Theme');
662
+
663
+ // Verify arrow variant styling
664
+ const paper = content?.closest('.MuiPaper-root') as HTMLElement;
665
+ if (paper) {
666
+ const computedStyle = window.getComputedStyle(paper);
667
+ expect(computedStyle.boxShadow).toBeTruthy();
668
+ }
669
+ });
670
+ await userEvent.keyboard('{Escape}');
671
+ });
672
+
673
+ statusElement.textContent = 'PASS';
674
+ },
675
+ };
676
+
677
+ // 8. Visual States Tests
678
+ export const VisualStates: Story = {
679
+ render: () => (
680
+ <>
681
+ <Stack spacing={2} direction="row">
682
+ <PopoverTestWrapper glow data-testid="glow-popover">
683
+ <Typography sx={{ p: 2 }} data-testid="glow-content">
684
+ Glow Effect
685
+ </Typography>
686
+ </PopoverTestWrapper>
687
+ <PopoverTestWrapper pulse data-testid="pulse-popover">
688
+ <Typography sx={{ p: 2 }} data-testid="pulse-content">
689
+ Pulse Effect
690
+ </Typography>
691
+ </PopoverTestWrapper>
692
+ <PopoverTestWrapper glow pulse data-testid="both-effects-popover">
693
+ <Typography sx={{ p: 2 }} data-testid="both-effects-content">
694
+ Both Effects
695
+ </Typography>
696
+ </PopoverTestWrapper>
697
+ </Stack>
698
+ <div aria-label="Status of the test run" style={{ marginTop: 20 }}>
699
+ PASS
700
+ </div>
701
+ </>
702
+ ),
703
+ play: async ({ canvasElement, step }) => {
704
+ const canvas = within(canvasElement);
705
+ const statusElement = canvas.getByLabelText('Status of the test run');
706
+ statusElement.textContent = 'RUNS';
707
+
708
+ await step('Should render and apply visual effect variants', async () => {
709
+ const triggers = canvas.getAllByTestId('popover-trigger');
710
+ expect(triggers).toHaveLength(3);
711
+
712
+ // Test glow effect
713
+ await userEvent.click(triggers[0]);
714
+ await waitFor(() => {
715
+ // Use document queries for portal-rendered content
716
+ const content = document.querySelector('[data-testid="glow-content"]');
717
+ expect(content).toBeInTheDocument();
718
+
719
+ // Verify glow effect is applied (enhanced box-shadow)
720
+ const paper = content?.closest('.MuiPaper-root') as HTMLElement;
721
+ if (paper) {
722
+ const computedStyle = window.getComputedStyle(paper);
723
+ expect(computedStyle.boxShadow).toContain('rgb');
724
+ expect(computedStyle.filter).toContain('brightness');
725
+ }
726
+ });
727
+ await userEvent.keyboard('{Escape}');
728
+
729
+ // Wait for close animation
730
+ await waitFor(() => {
731
+ expect(document.querySelector('[data-testid="glow-content"]')).not.toBeInTheDocument();
732
+ });
733
+
734
+ // Test pulse effect
735
+ await userEvent.click(triggers[1]);
736
+ await waitFor(() => {
737
+ // Use document queries for portal-rendered content
738
+ const content = document.querySelector('[data-testid="pulse-content"]');
739
+ expect(content).toBeInTheDocument();
740
+
741
+ // Verify pulse animation is present
742
+ const paper = content?.closest('.MuiPaper-root') as HTMLElement;
743
+ if (paper) {
744
+ // Check for ::after pseudo element that creates pulse
745
+ const computedStyle = window.getComputedStyle(paper, '::after');
746
+ expect(computedStyle.animation || computedStyle.animationName).toBeTruthy();
747
+ }
748
+ });
749
+ await userEvent.keyboard('{Escape}');
750
+
751
+ // Wait for close animation
752
+ await waitFor(() => {
753
+ expect(document.querySelector('[data-testid="pulse-content"]')).not.toBeInTheDocument();
754
+ });
755
+
756
+ // Test both effects combined
757
+ await userEvent.click(triggers[2]);
758
+ await waitFor(() => {
759
+ // Use document queries for portal-rendered content
760
+ const content = document.querySelector('[data-testid="both-effects-content"]');
761
+ expect(content).toBeInTheDocument();
762
+
763
+ // Verify both effects are applied
764
+ const paper = content?.closest('.MuiPaper-root') as HTMLElement;
765
+ if (paper) {
766
+ const computedStyle = window.getComputedStyle(paper);
767
+ // Should have glow shadow
768
+ expect(computedStyle.boxShadow).toContain('rgb');
769
+ expect(computedStyle.filter).toContain('brightness');
770
+ // Should have pulse animation
771
+ const afterStyle = window.getComputedStyle(paper, '::after');
772
+ expect(afterStyle.animation || afterStyle.animationName).toBeTruthy();
773
+ }
774
+ });
775
+ await userEvent.keyboard('{Escape}');
776
+ });
777
+
778
+ statusElement.textContent = 'PASS';
779
+ },
780
+ };
781
+
782
+ // 9. Performance Tests
783
+ const PerformanceTestComponent = () => {
784
+ const [renderCount, setRenderCount] = React.useState(0);
785
+ const [openCount, setOpenCount] = React.useState(0);
786
+
787
+ React.useEffect(() => {
788
+ setRenderCount((c) => c + 1);
789
+ }, []);
790
+
791
+ return (
792
+ <div>
793
+ <div data-testid="render-count">Renders: {renderCount}</div>
794
+ <div data-testid="open-count" style={{ display: 'none' }}>
795
+ Opens: {openCount}
796
+ </div>
797
+ <PopoverTestWrapper onOpen={() => setOpenCount((c) => c + 1)}>
798
+ <div style={{ padding: 16 }}>
799
+ <Typography variant="h6">Performance Test</Typography>
800
+ <Typography data-testid="performance-content">
801
+ This tests if the popover triggers excessive re-renders.
802
+ </Typography>
803
+ </div>
804
+ </PopoverTestWrapper>
805
+ <div aria-label="Status of the test run" style={{ marginTop: 20 }}>
806
+ PASS
807
+ </div>
808
+ </div>
809
+ );
810
+ };
811
+
812
+ export const Performance: Story = {
813
+ render: () => <PerformanceTestComponent />,
814
+ play: async ({ canvasElement, step }) => {
815
+ const canvas = within(canvasElement);
816
+ const statusElement = canvas.getByLabelText('Status of the test run');
817
+ statusElement.textContent = 'RUNS';
818
+
819
+ await step('Should not cause excessive re-renders during interactions', async () => {
820
+ const renderCountElement = canvas.getByTestId('render-count');
821
+ const initialRenders = parseInt(renderCountElement.textContent?.split(': ')[1] || '0');
822
+
823
+ // Open and close popover multiple times
824
+ const trigger = canvas.getByTestId('popover-trigger');
825
+
826
+ // First open/close cycle
827
+ await userEvent.click(trigger);
828
+ await waitFor(() => {
829
+ expect(document.querySelector('[data-testid="performance-content"]')).toBeInTheDocument();
830
+ });
831
+ await userEvent.keyboard('{Escape}');
832
+ await waitFor(() => {
833
+ expect(
834
+ document.querySelector('[data-testid="performance-content"]'),
835
+ ).not.toBeInTheDocument();
836
+ });
837
+
838
+ // Second open/close cycle
839
+ await userEvent.click(trigger);
840
+ await waitFor(() => {
841
+ expect(document.querySelector('[data-testid="performance-content"]')).toBeInTheDocument();
842
+ });
843
+ await userEvent.keyboard('{Escape}');
844
+ await waitFor(() => {
845
+ expect(
846
+ document.querySelector('[data-testid="performance-content"]'),
847
+ ).not.toBeInTheDocument();
848
+ });
849
+
850
+ // Third open/close cycle
851
+ await userEvent.click(trigger);
852
+ await waitFor(() => {
853
+ expect(document.querySelector('[data-testid="performance-content"]')).toBeInTheDocument();
854
+ });
855
+ await userEvent.keyboard('{Escape}');
856
+ await waitFor(() => {
857
+ expect(
858
+ document.querySelector('[data-testid="performance-content"]'),
859
+ ).not.toBeInTheDocument();
860
+ });
861
+
862
+ // Check that renders didn't increase dramatically
863
+ const finalRenders = parseInt(
864
+ canvas.getByTestId('render-count').textContent?.split(': ')[1] || '0',
865
+ );
866
+ expect(finalRenders - initialRenders).toBeLessThan(10);
867
+
868
+ // Verify open count matches expected
869
+ const openCount = parseInt(
870
+ canvas.getByTestId('open-count').textContent?.split(': ')[1] || '0',
871
+ );
872
+ expect(openCount).toBe(3);
873
+ });
874
+
875
+ await step('Should handle rapid open/close without performance degradation', async () => {
876
+ const trigger = canvas.getByTestId('popover-trigger');
877
+ const startTime = Date.now();
878
+
879
+ // Rapid open/close
880
+ for (let i = 0; i < 5; i++) {
881
+ await userEvent.click(trigger);
882
+ await userEvent.keyboard('{Escape}');
883
+ }
884
+
885
+ const endTime = Date.now();
886
+ const duration = endTime - startTime;
887
+
888
+ // Should complete rapid interactions within reasonable time (5 seconds)
889
+ expect(duration).toBeLessThan(5000);
890
+ });
891
+
892
+ statusElement.textContent = 'PASS';
893
+ },
894
+ };
895
+
896
+ // 10. Edge Cases Tests
897
+ export const EdgeCases: Story = {
898
+ render: () => (
899
+ <>
900
+ <Stack spacing={2}>
901
+ {/* Empty content */}
902
+ <PopoverTestWrapper data-testid="empty-popover">
903
+ <div style={{ padding: 16, minHeight: 50 }} data-testid="empty-content" />
904
+ </PopoverTestWrapper>
905
+
906
+ {/* Very long content */}
907
+ <PopoverTestWrapper maxWidth={200} data-testid="long-content-popover">
908
+ <Typography sx={{ p: 2 }} data-testid="long-content">
909
+ This is a very long text content that should wrap properly and not break the popover
910
+ layout. It should handle overflow gracefully and maintain proper spacing and typography.
911
+ Additional text to ensure wrapping behavior is tested thoroughly.
912
+ </Typography>
913
+ </PopoverTestWrapper>
914
+
915
+ {/* No maxWidth */}
916
+ <PopoverTestWrapper maxWidth={undefined} data-testid="no-max-width-popover">
917
+ <Typography sx={{ p: 2 }} data-testid="no-max-width-content">
918
+ Content without maxWidth constraint should expand naturally
919
+ </Typography>
920
+ </PopoverTestWrapper>
921
+
922
+ {/* Zero maxWidth edge case */}
923
+ <PopoverTestWrapper maxWidth={0} data-testid="zero-width-popover">
924
+ <Typography sx={{ p: 2 }} data-testid="zero-width-content">
925
+ Zero width test
926
+ </Typography>
927
+ </PopoverTestWrapper>
928
+ </Stack>
929
+ <div aria-label="Status of the test run" style={{ marginTop: 20 }}>
930
+ PASS
931
+ </div>
932
+ </>
933
+ ),
934
+ play: async ({ canvasElement, step }) => {
935
+ const canvas = within(canvasElement);
936
+ const statusElement = canvas.getByLabelText('Status of the test run');
937
+ statusElement.textContent = 'RUNS';
938
+
939
+ await step('Should handle empty content gracefully', async () => {
940
+ const triggers = canvas.getAllByTestId('popover-trigger');
941
+ await userEvent.click(triggers[0]);
942
+
943
+ await waitFor(() => {
944
+ // Use document queries for portal-rendered content
945
+ const emptyContent = document.querySelector('[data-testid="empty-content"]');
946
+ expect(emptyContent).toBeInTheDocument();
947
+
948
+ // Verify minimum height is applied
949
+ const computedStyle = window.getComputedStyle(emptyContent as HTMLElement);
950
+ expect(computedStyle.minHeight).toBe('50px');
951
+
952
+ // Verify popover renders even with empty content
953
+ const paper = emptyContent?.closest('.MuiPaper-root');
954
+ expect(paper).toBeInTheDocument();
955
+ });
956
+ await userEvent.keyboard('{Escape}');
957
+ });
958
+
959
+ await step('Should handle long content with proper text wrapping', async () => {
960
+ const triggers = canvas.getAllByTestId('popover-trigger');
961
+ await userEvent.click(triggers[1]);
962
+
963
+ await waitFor(() => {
964
+ // Use document queries for portal-rendered content
965
+ const content = document.querySelector('[data-testid="long-content"]') as HTMLElement;
966
+ expect(content).toBeInTheDocument();
967
+
968
+ // Verify maxWidth is applied
969
+ const paper = content?.closest('.MuiPaper-root') as HTMLElement;
970
+ if (paper) {
971
+ const computedStyle = window.getComputedStyle(paper);
972
+ expect(computedStyle.maxWidth).toBe('200px');
973
+ }
974
+
975
+ // Verify text wraps properly
976
+ const contentHeight = content?.offsetHeight;
977
+ expect(contentHeight).toBeGreaterThan(50); // Should be taller due to wrapping
978
+ });
979
+ await userEvent.keyboard('{Escape}');
980
+ });
981
+
982
+ await step('Should handle content without maxWidth constraint', async () => {
983
+ const triggers = canvas.getAllByTestId('popover-trigger');
984
+ await userEvent.click(triggers[2]);
985
+
986
+ await waitFor(() => {
987
+ // Use document queries for portal-rendered content
988
+ const content = document.querySelector('[data-testid="no-max-width-content"]');
989
+ expect(content).toBeInTheDocument();
990
+
991
+ // Verify no maxWidth constraint is applied (should use default)
992
+ const paper = content?.closest('.MuiPaper-root') as HTMLElement;
993
+ if (paper) {
994
+ const computedStyle = window.getComputedStyle(paper);
995
+ // When undefined, should use default maxWidth of 400px
996
+ expect(computedStyle.maxWidth).toBe('400px');
997
+ }
998
+ });
999
+ await userEvent.keyboard('{Escape}');
1000
+ });
1001
+
1002
+ await step('Should handle zero maxWidth edge case', async () => {
1003
+ const triggers = canvas.getAllByTestId('popover-trigger');
1004
+ await userEvent.click(triggers[3]);
1005
+
1006
+ await waitFor(() => {
1007
+ // Use document queries for portal-rendered content
1008
+ const content = document.querySelector('[data-testid="zero-width-content"]');
1009
+ expect(content).toBeInTheDocument();
1010
+
1011
+ // Verify zero maxWidth is handled
1012
+ const paper = content?.closest('.MuiPaper-root') as HTMLElement;
1013
+ if (paper) {
1014
+ const computedStyle = window.getComputedStyle(paper);
1015
+ expect(computedStyle.maxWidth).toBe('0px');
1016
+ }
1017
+ });
1018
+ await userEvent.keyboard('{Escape}');
1019
+ });
1020
+
1021
+ statusElement.textContent = 'PASS';
1022
+ },
1023
+ };
1024
+
1025
+ // 11. Integration Tests
1026
+ const IntegrationTestComponent = () => {
1027
+ const [selectedItem, setSelectedItem] = React.useState<string>('');
1028
+ const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null);
1029
+ const isOpen = Boolean(anchorEl);
1030
+
1031
+ const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
1032
+ setAnchorEl(event.currentTarget);
1033
+ };
1034
+
1035
+ const handleClose = () => {
1036
+ setAnchorEl(null);
1037
+ };
1038
+
1039
+ const handleItemClick = (option: string) => {
1040
+ setSelectedItem(option);
1041
+ handleClose(); // Properly close popover after selection
1042
+ };
1043
+
1044
+ return (
1045
+ <>
1046
+ <div>
1047
+ <Typography data-testid="selected-item">Selected: {selectedItem || 'None'}</Typography>
1048
+ <Button variant="contained" onClick={handleClick} data-testid="popover-trigger">
1049
+ Open Popover
1050
+ </Button>
1051
+ <Popover
1052
+ open={isOpen}
1053
+ anchorEl={anchorEl}
1054
+ onClose={handleClose}
1055
+ anchorOrigin={{
1056
+ vertical: 'bottom',
1057
+ horizontal: 'left',
1058
+ }}
1059
+ data-testid="popover"
1060
+ >
1061
+ <div style={{ padding: 16 }}>
1062
+ <Typography variant="h6" gutterBottom>
1063
+ Select an Option
1064
+ </Typography>
1065
+ <List dense>
1066
+ {['Option 1', 'Option 2', 'Option 3'].map((option) => (
1067
+ <ListItem
1068
+ key={option}
1069
+ component="button"
1070
+ data-testid={`option-${option.toLowerCase().replace(' ', '-')}`}
1071
+ onClick={() => handleItemClick(option)}
1072
+ >
1073
+ <ListItemText primary={option} />
1074
+ </ListItem>
1075
+ ))}
1076
+ </List>
1077
+ </div>
1078
+ </Popover>
1079
+ <Typography data-testid="popover-state" style={{ display: 'none' }}>
1080
+ {isOpen ? 'open' : 'closed'}
1081
+ </Typography>
1082
+ </div>
1083
+ <div aria-label="Status of the test run" style={{ marginTop: 20 }}>
1084
+ PASS
1085
+ </div>
1086
+ </>
1087
+ );
1088
+ };
1089
+
1090
+ export const Integration: Story = {
1091
+ render: () => <IntegrationTestComponent />,
1092
+ play: async ({ canvasElement, step }) => {
1093
+ const canvas = within(canvasElement);
1094
+ const statusElement = canvas.getByLabelText('Status of the test run');
1095
+ statusElement.textContent = 'RUNS';
1096
+
1097
+ await step('Should integrate with external state management', async () => {
1098
+ // Verify initial state
1099
+ expect(canvas.getByTestId('selected-item')).toHaveTextContent('Selected: None');
1100
+ expect(canvas.getByTestId('popover-state')).toHaveTextContent('closed');
1101
+
1102
+ const trigger = canvas.getByTestId('popover-trigger');
1103
+ await userEvent.click(trigger);
1104
+
1105
+ await waitFor(() => {
1106
+ expect(canvas.getByTestId('popover-state')).toHaveTextContent('open');
1107
+ // Use document queries for portal-rendered content
1108
+ expect(document.querySelector('[data-testid="option-option-1"]')).toBeInTheDocument();
1109
+ expect(document.querySelector('[data-testid="option-option-2"]')).toBeInTheDocument();
1110
+ expect(document.querySelector('[data-testid="option-option-3"]')).toBeInTheDocument();
1111
+ });
1112
+
1113
+ // Click an option
1114
+ const option2 = document.querySelector('[data-testid="option-option-2"]') as HTMLElement;
1115
+ await userEvent.click(option2);
1116
+
1117
+ // Should update external state and close popover
1118
+ await waitFor(() => {
1119
+ expect(canvas.getByTestId('selected-item')).toHaveTextContent('Selected: Option 2');
1120
+ expect(canvas.getByTestId('popover-state')).toHaveTextContent('closed');
1121
+ });
1122
+
1123
+ // Wait for popover content to be removed from DOM
1124
+ await waitFor(
1125
+ () => {
1126
+ expect(document.querySelector('[data-testid="option-option-1"]')).not.toBeInTheDocument();
1127
+ },
1128
+ { timeout: 2000 },
1129
+ );
1130
+ });
1131
+
1132
+ await step('Should maintain state across multiple interactions', async () => {
1133
+ // Open again and select different option
1134
+ const trigger = canvas.getByTestId('popover-trigger');
1135
+ await userEvent.click(trigger);
1136
+
1137
+ await waitFor(() => {
1138
+ expect(canvas.getByTestId('popover-state')).toHaveTextContent('open');
1139
+ });
1140
+
1141
+ const option3 = document.querySelector('[data-testid="option-option-3"]') as HTMLElement;
1142
+ await userEvent.click(option3);
1143
+
1144
+ await waitFor(() => {
1145
+ expect(canvas.getByTestId('selected-item')).toHaveTextContent('Selected: Option 3');
1146
+ expect(canvas.getByTestId('popover-state')).toHaveTextContent('closed');
1147
+ });
1148
+
1149
+ // Open again and select first option
1150
+ await userEvent.click(trigger);
1151
+
1152
+ await waitFor(() => {
1153
+ // Use document query for portal-rendered content
1154
+ expect(document.querySelector('[data-testid="option-option-1"]')).toBeInTheDocument();
1155
+ });
1156
+
1157
+ const option1 = document.querySelector('[data-testid="option-option-1"]') as HTMLElement;
1158
+ await userEvent.click(option1);
1159
+
1160
+ await waitFor(() => {
1161
+ expect(canvas.getByTestId('selected-item')).toHaveTextContent('Selected: Option 1');
1162
+ expect(canvas.getByTestId('popover-state')).toHaveTextContent('closed');
1163
+ });
1164
+ });
1165
+
1166
+ statusElement.textContent = 'PASS';
1167
+ },
1168
+ };