@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,1074 @@
1
+ import {
2
+ Alert,
3
+ Avatar,
4
+ Box,
5
+ ListItem,
6
+ ListItemAvatar,
7
+ ListItemText,
8
+ Paper,
9
+ Skeleton,
10
+ Typography,
11
+ } from '@mui/material';
12
+ import type { Meta, StoryObj } from '@storybook/react-vite';
13
+ import { expect, fireEvent,fn, userEvent, waitFor, within } from 'storybook/test';
14
+
15
+ import { VirtualGrid,VirtualList } from './VirtualList';
16
+ import type { VirtualListItem } from './VirtualList.types';
17
+
18
+ const meta: Meta<typeof VirtualList> = {
19
+ title: 'Utility/VirtualList/Tests',
20
+ component: VirtualList,
21
+ parameters: {
22
+ layout: 'centered',
23
+ chromatic: { disableSnapshot: false },
24
+ },
25
+ tags: ['autodocs', 'test', 'component:VirtualList'],
26
+ };
27
+
28
+ export default meta;
29
+ type Story = StoryObj<typeof meta>;
30
+
31
+ // Helper functions
32
+ const generateItems = (count: number): VirtualListItem[] => Array.from({ length: count }, (_, i) => ({
33
+ id: i,
34
+ data: {
35
+ name: `Item ${i + 1}`,
36
+ description: `This is the description for item ${i + 1}`,
37
+ avatar: `https://i.pravatar.cc/40?img=${(i % 70) + 1}`,
38
+ },
39
+ }));
40
+
41
+ const generateVariableItems = (count: number): VirtualListItem[] => Array.from({ length: count }, (_, i) => ({
42
+ id: i,
43
+ height: 60 + Math.floor(Math.random() * 100),
44
+ data: {
45
+ name: `Variable Item ${i + 1}`,
46
+ description: `This item has a variable height. ${
47
+ Math.random() > 0.5
48
+ ? 'It contains additional content that makes it taller than other items in the list.'
49
+ : 'Short description.'
50
+ }`,
51
+ avatar: `https://i.pravatar.cc/40?img=${(i % 70) + 1}`,
52
+ },
53
+ }));
54
+
55
+ const SimpleItemRenderer = ({
56
+ item,
57
+ index,
58
+ style,
59
+ }: {
60
+ item: VirtualListItem;
61
+ index: number;
62
+ style: React.CSSProperties;
63
+ }) => (
64
+ <Box key={item.id} style={style} data-testid={`virtual-item-${index}`}>
65
+ <ListItem>
66
+ <ListItemAvatar>
67
+ <Avatar src={item.data.avatar} />
68
+ </ListItemAvatar>
69
+ <ListItemText primary={item.data.name} secondary={item.data.description} />
70
+ </ListItem>
71
+ </Box>
72
+ );
73
+
74
+ const GridItemRenderer = ({
75
+ item,
76
+ index,
77
+ style,
78
+ }: {
79
+ item: VirtualListItem;
80
+ index: number;
81
+ style: React.CSSProperties;
82
+ }) => (
83
+ <Box
84
+ key={item.id}
85
+ style={style}
86
+ data-testid={`grid-item-${index}`}
87
+ sx={{
88
+ p: 2,
89
+ bgcolor: 'background.paper',
90
+ border: '1px solid',
91
+ borderColor: 'divider',
92
+ borderRadius: 2,
93
+ display: 'flex',
94
+ flexDirection: 'column',
95
+ alignItems: 'center',
96
+ textAlign: 'center',
97
+ }}
98
+ >
99
+ <Avatar src={item.data.avatar} sx={{ width: 56, height: 56, mb: 1 }} />
100
+ <Typography variant="body2" fontWeight="bold">
101
+ {item.data.name}
102
+ </Typography>
103
+ <Typography variant="caption" color="text.secondary">
104
+ Grid Item #{item.id + 1}
105
+ </Typography>
106
+ </Box>
107
+ );
108
+
109
+ // Basic Interaction Tests
110
+ export const BasicInteraction: Story = {
111
+ render: () => {
112
+ const items = generateItems(100);
113
+ const onScrollSpy = fn();
114
+
115
+ return (
116
+ <Paper sx={{ width: 400, height: 300 }}>
117
+ <VirtualList
118
+ items={items}
119
+ variant="fixed"
120
+ height={300}
121
+ itemHeight={60}
122
+ onScroll={onScrollSpy}
123
+ renderItem={SimpleItemRenderer}
124
+ data-testid="virtual-list"
125
+ />
126
+ </Paper>
127
+ );
128
+ },
129
+ play: async ({ canvasElement }) => {
130
+ const canvas = within(canvasElement);
131
+ const virtualList = canvas.getByTestId('virtual-list');
132
+
133
+ // Test that virtual list renders
134
+ await expect(virtualList).toBeInTheDocument();
135
+
136
+ // Test that items are rendered
137
+ const firstItem = canvas.getByTestId('virtual-item-0');
138
+ await expect(firstItem).toBeInTheDocument();
139
+
140
+ // Test scrolling
141
+ fireEvent.scroll(virtualList, { target: { scrollTop: 200 } });
142
+ await waitFor(() => {
143
+ // After scrolling, different items should be visible
144
+ const newVisibleItem = canvas.queryByTestId('virtual-item-5');
145
+ expect(newVisibleItem).toBeInTheDocument();
146
+ });
147
+
148
+ // Test that scroll callback is called
149
+ await waitFor(() => {
150
+ expect(virtualList.scrollTop).toBeGreaterThan(0);
151
+ });
152
+ },
153
+ };
154
+
155
+ export const GridInteraction: Story = {
156
+ render: () => {
157
+ const items = generateItems(100);
158
+ const onScrollSpy = fn();
159
+
160
+ return (
161
+ <Paper sx={{ width: 600, height: 400 }}>
162
+ <VirtualGrid
163
+ items={items}
164
+ height={400}
165
+ width={600}
166
+ columnCount={3}
167
+ rowHeight={150}
168
+ gap={8}
169
+ onScroll={onScrollSpy}
170
+ renderItem={GridItemRenderer}
171
+ data-testid="virtual-grid"
172
+ />
173
+ </Paper>
174
+ );
175
+ },
176
+ play: async ({ canvasElement }) => {
177
+ const canvas = within(canvasElement);
178
+ const virtualGrid = canvas.getByTestId('virtual-grid');
179
+
180
+ // Test that virtual grid renders
181
+ await expect(virtualGrid).toBeInTheDocument();
182
+
183
+ // Test that grid items are rendered
184
+ const firstItem = canvas.getByTestId('grid-item-0');
185
+ await expect(firstItem).toBeInTheDocument();
186
+
187
+ // Test multiple items in first row
188
+ const secondItem = canvas.getByTestId('grid-item-1');
189
+ const thirdItem = canvas.getByTestId('grid-item-2');
190
+ await expect(secondItem).toBeInTheDocument();
191
+ await expect(thirdItem).toBeInTheDocument();
192
+
193
+ // Test scrolling in grid
194
+ fireEvent.scroll(virtualGrid, { target: { scrollTop: 300 } });
195
+ await waitFor(() => {
196
+ expect(virtualGrid.scrollTop).toBeGreaterThan(0);
197
+ });
198
+ },
199
+ };
200
+
201
+ // Form Interaction Tests (Scroll behaviors)
202
+ export const ScrollInteraction: Story = {
203
+ render: () => {
204
+ const items = generateItems(1000);
205
+ let scrollPosition = 0;
206
+
207
+ return (
208
+ <Box sx={{ display: 'flex', gap: 2 }}>
209
+ <Paper sx={{ width: 400, height: 300 }}>
210
+ <VirtualList
211
+ items={items}
212
+ variant="fixed"
213
+ height={300}
214
+ itemHeight={50}
215
+ onScroll={(scrollTop) => {
216
+ scrollPosition = scrollTop;
217
+ }}
218
+ renderItem={SimpleItemRenderer}
219
+ data-testid="scrollable-list"
220
+ />
221
+ </Paper>
222
+ <Box sx={{ width: 200, p: 2 }}>
223
+ <Typography variant="body2" data-testid="scroll-info">
224
+ Scroll Position: {Math.round(scrollPosition)}px
225
+ </Typography>
226
+ </Box>
227
+ </Box>
228
+ );
229
+ },
230
+ play: async ({ canvasElement }) => {
231
+ const canvas = within(canvasElement);
232
+ const scrollableList = canvas.getByTestId('scrollable-list');
233
+
234
+ // Test initial state
235
+ await expect(scrollableList).toBeInTheDocument();
236
+ expect(scrollableList.scrollTop).toBe(0);
237
+
238
+ // Test scroll to middle
239
+ fireEvent.scroll(scrollableList, { target: { scrollTop: 500 } });
240
+ await waitFor(() => {
241
+ expect(scrollableList.scrollTop).toBeGreaterThan(400);
242
+ });
243
+
244
+ // Test scroll to bottom
245
+ scrollableList.scrollTop = scrollableList.scrollHeight - scrollableList.clientHeight;
246
+ await waitFor(() => {
247
+ expect(scrollableList.scrollTop).toBeGreaterThan(1000);
248
+ });
249
+
250
+ // Test scroll back to top
251
+ scrollableList.scrollTop = 0;
252
+ await waitFor(() => {
253
+ expect(scrollableList.scrollTop).toBe(0);
254
+ });
255
+ },
256
+ };
257
+
258
+ // Keyboard Navigation Tests
259
+ export const KeyboardNavigation: Story = {
260
+ render: () => {
261
+ const items = generateItems(100);
262
+
263
+ return (
264
+ <Paper sx={{ width: 400, height: 300 }}>
265
+ <VirtualList
266
+ items={items}
267
+ variant="fixed"
268
+ height={300}
269
+ itemHeight={60}
270
+ renderItem={({ item, index, style }) => (
271
+ <Box key={item.id} style={style}>
272
+ <ListItem
273
+ tabIndex={0}
274
+ data-testid={`keyboard-item-${index}`}
275
+ sx={{
276
+ '&:focus': {
277
+ backgroundColor: 'primary.light',
278
+ outline: '2px solid',
279
+ outlineColor: 'primary.main',
280
+ },
281
+ }}
282
+ >
283
+ <ListItemAvatar>
284
+ <Avatar src={item.data.avatar} />
285
+ </ListItemAvatar>
286
+ <ListItemText primary={item.data.name} secondary={item.data.description} />
287
+ </ListItem>
288
+ </Box>
289
+ )}
290
+ data-testid="keyboard-list"
291
+ />
292
+ </Paper>
293
+ );
294
+ },
295
+ play: async ({ canvasElement }) => {
296
+ const canvas = within(canvasElement);
297
+ const list = canvas.getByTestId('keyboard-list');
298
+
299
+ // Test initial focus
300
+ const firstItem = canvas.getByTestId('keyboard-item-0');
301
+ await userEvent.click(firstItem);
302
+ await waitFor(() => {
303
+ expect(firstItem).toHaveFocus();
304
+ });
305
+
306
+ // Test that second item can be focused (simulate arrow key behavior)
307
+ const secondItem = canvas.getByTestId('keyboard-item-1');
308
+ await userEvent.click(secondItem);
309
+ await waitFor(() => {
310
+ expect(secondItem).toHaveFocus();
311
+ });
312
+
313
+ // Test scroll behavior using direct scroll event
314
+ fireEvent.scroll(list, { target: { scrollTop: 200 } });
315
+ await waitFor(
316
+ () => {
317
+ // Check the scroll position was applied
318
+ expect(list.scrollTop).toBeGreaterThan(0);
319
+ },
320
+ { timeout: 2000 },
321
+ );
322
+
323
+ // Test scroll back to top
324
+ fireEvent.scroll(list, { target: { scrollTop: 0 } });
325
+ await waitFor(
326
+ () => {
327
+ expect(list.scrollTop).toBe(0);
328
+ },
329
+ { timeout: 1000 },
330
+ );
331
+ },
332
+ };
333
+
334
+ // Screen Reader Tests
335
+ export const ScreenReader: Story = {
336
+ render: () => {
337
+ const items = generateItems(50);
338
+
339
+ return (
340
+ <Paper sx={{ width: 400, height: 300 }}>
341
+ <VirtualList
342
+ items={items}
343
+ variant="fixed"
344
+ height={300}
345
+ itemHeight={80}
346
+ renderItem={({ item, index, style }) => (
347
+ <Box key={item.id} style={style}>
348
+ <ListItem
349
+ role="listitem"
350
+ aria-label={`Item ${index + 1}: ${item.data.name}`}
351
+ data-testid={`screen-reader-item-${index}`}
352
+ >
353
+ <ListItemAvatar>
354
+ <Avatar src={item.data.avatar} alt={`Avatar for ${item.data.name}`} />
355
+ </ListItemAvatar>
356
+ <ListItemText primary={item.data.name} secondary={item.data.description} />
357
+ </ListItem>
358
+ </Box>
359
+ )}
360
+ role="list"
361
+ aria-label="Virtual scrollable list"
362
+ data-testid="screen-reader-list"
363
+ />
364
+ </Paper>
365
+ );
366
+ },
367
+ play: async ({ canvasElement }) => {
368
+ const canvas = within(canvasElement);
369
+ const list = canvas.getByTestId('screen-reader-list');
370
+
371
+ // Test ARIA attributes
372
+ await expect(list).toHaveAttribute('role', 'list');
373
+ await expect(list).toHaveAttribute('aria-label', 'Virtual scrollable list');
374
+
375
+ // Test item accessibility
376
+ const firstItem = canvas.getByTestId('screen-reader-item-0');
377
+ await expect(firstItem).toHaveAttribute('role', 'listitem');
378
+ await expect(firstItem).toHaveAttribute('aria-label');
379
+
380
+ // Test that aria-label contains descriptive text
381
+ const ariaLabel = firstItem.getAttribute('aria-label');
382
+ expect(ariaLabel).toContain('Item 1:');
383
+
384
+ // Test avatar alt text
385
+ const avatar = firstItem.querySelector('img');
386
+ if (avatar) {
387
+ expect(avatar).toHaveAttribute('alt');
388
+ }
389
+ },
390
+ };
391
+
392
+ // Focus Management Tests
393
+ export const FocusManagement: Story = {
394
+ render: () => {
395
+ const items = generateItems(20);
396
+
397
+ return (
398
+ <Box sx={{ display: 'flex', gap: 2, alignItems: 'flex-start' }}>
399
+ <button data-testid="external-button">External Button</button>
400
+ <Paper sx={{ width: 400, height: 250 }}>
401
+ <VirtualList
402
+ items={items}
403
+ variant="fixed"
404
+ height={250}
405
+ itemHeight={60}
406
+ renderItem={({ item, index, style }) => (
407
+ <Box key={item.id} style={style}>
408
+ <ListItem
409
+ button
410
+ tabIndex={0}
411
+ data-testid={`focus-item-${index}`}
412
+ onFocus={(e) => {
413
+ e.currentTarget.scrollIntoView({ block: 'nearest' });
414
+ }}
415
+ >
416
+ <ListItemAvatar>
417
+ <Avatar src={item.data.avatar} />
418
+ </ListItemAvatar>
419
+ <ListItemText primary={item.data.name} secondary={item.data.description} />
420
+ </ListItem>
421
+ </Box>
422
+ )}
423
+ data-testid="focus-list"
424
+ />
425
+ </Paper>
426
+ </Box>
427
+ );
428
+ },
429
+ play: async ({ canvasElement }) => {
430
+ const canvas = within(canvasElement);
431
+
432
+ // Test external focus
433
+ const externalButton = canvas.getByTestId('external-button');
434
+ await userEvent.click(externalButton);
435
+ expect(externalButton).toHaveFocus();
436
+
437
+ // Test tab into list
438
+ await userEvent.tab();
439
+ const firstItem = canvas.getByTestId('focus-item-0');
440
+ await waitFor(() => {
441
+ expect(firstItem).toHaveFocus();
442
+ });
443
+
444
+ // Test focus preservation during scroll
445
+ const list = canvas.getByTestId('focus-list');
446
+ fireEvent.scroll(list, { target: { scrollTop: 200 } });
447
+
448
+ // Focus should remain stable
449
+ await waitFor(() => {
450
+ const focusedElement = canvasElement.ownerDocument.activeElement;
451
+ expect(focusedElement?.getAttribute('data-testid')).toContain('focus-item-');
452
+ });
453
+ },
454
+ };
455
+
456
+ // Responsive Design Tests
457
+ export const ResponsiveDesign: Story = {
458
+ render: () => {
459
+ const items = generateItems(100);
460
+
461
+ return (
462
+ <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2, width: '100%' }}>
463
+ {/* Mobile viewport */}
464
+ <Paper sx={{ width: 320, height: 200 }}>
465
+ <Typography variant="caption" sx={{ p: 1, display: 'block' }}>
466
+ Mobile (320px)
467
+ </Typography>
468
+ <VirtualList
469
+ items={items}
470
+ variant="fixed"
471
+ height={180}
472
+ width={320}
473
+ itemHeight={50}
474
+ renderItem={({ item, style }) => (
475
+ <Box key={item.id} style={style}>
476
+ <ListItem sx={{ px: 1 }}>
477
+ <ListItemAvatar>
478
+ <Avatar src={item.data.avatar} sx={{ width: 32, height: 32 }} />
479
+ </ListItemAvatar>
480
+ <ListItemText
481
+ primary={
482
+ <Typography variant="body2" noWrap>
483
+ {item.data.name}
484
+ </Typography>
485
+ }
486
+ />
487
+ </ListItem>
488
+ </Box>
489
+ )}
490
+ data-testid="mobile-list"
491
+ />
492
+ </Paper>
493
+
494
+ {/* Desktop viewport */}
495
+ <Paper sx={{ width: 800, height: 200 }}>
496
+ <Typography variant="caption" sx={{ p: 1, display: 'block' }}>
497
+ Desktop (800px)
498
+ </Typography>
499
+ <VirtualList
500
+ items={items}
501
+ variant="fixed"
502
+ height={180}
503
+ width={800}
504
+ itemHeight={60}
505
+ renderItem={({ item, style }) => (
506
+ <Box key={item.id} style={style}>
507
+ <ListItem sx={{ px: 3 }}>
508
+ <ListItemAvatar>
509
+ <Avatar src={item.data.avatar} sx={{ width: 48, height: 48 }} />
510
+ </ListItemAvatar>
511
+ <ListItemText primary={item.data.name} secondary={item.data.description} />
512
+ </ListItem>
513
+ </Box>
514
+ )}
515
+ data-testid="desktop-list"
516
+ />
517
+ </Paper>
518
+ </Box>
519
+ );
520
+ },
521
+ play: async ({ canvasElement }) => {
522
+ const canvas = within(canvasElement);
523
+
524
+ // Test mobile list
525
+ const mobileList = canvas.getByTestId('mobile-list');
526
+ await expect(mobileList).toBeInTheDocument();
527
+
528
+ // Check that mobile list container exists
529
+ const mobileContainer = mobileList.closest(
530
+ '[role="list"], .virtual-list, [data-testid="mobile-list"]',
531
+ );
532
+ expect(mobileContainer).toBeInTheDocument();
533
+
534
+ // Test desktop list
535
+ const desktopList = canvas.getByTestId('desktop-list');
536
+ await expect(desktopList).toBeInTheDocument();
537
+
538
+ // Check that desktop list container exists
539
+ const desktopContainer = desktopList.closest(
540
+ '[role="list"], .virtual-list, [data-testid="desktop-list"]',
541
+ );
542
+ expect(desktopContainer).toBeInTheDocument();
543
+
544
+ // Test that both lists have content (look for any rendered items)
545
+ await waitFor(
546
+ () => {
547
+ expect(mobileList.children.length).toBeGreaterThan(0);
548
+ },
549
+ { timeout: 2000 },
550
+ );
551
+
552
+ await waitFor(
553
+ () => {
554
+ expect(desktopList.children.length).toBeGreaterThan(0);
555
+ },
556
+ { timeout: 2000 },
557
+ );
558
+ },
559
+ };
560
+
561
+ // Theme Variations Tests
562
+ export const ThemeVariations: Story = {
563
+ render: () => {
564
+ const items = generateItems(50);
565
+
566
+ return (
567
+ <Box sx={{ display: 'flex', gap: 2 }}>
568
+ {/* Light theme */}
569
+ <Paper sx={{ width: 300, height: 250, bgcolor: 'background.paper' }}>
570
+ <Typography variant="caption" sx={{ p: 1, display: 'block' }}>
571
+ Light Theme
572
+ </Typography>
573
+ <VirtualList
574
+ items={items}
575
+ variant="fixed"
576
+ height={220}
577
+ itemHeight={55}
578
+ renderItem={({ item, style }) => (
579
+ <Box key={item.id} style={style}>
580
+ <ListItem sx={{ borderBottom: '1px solid', borderColor: 'divider' }}>
581
+ <ListItemAvatar>
582
+ <Avatar src={item.data.avatar} />
583
+ </ListItemAvatar>
584
+ <ListItemText
585
+ primary={<Typography color="text.primary">{item.data.name}</Typography>}
586
+ secondary={
587
+ <Typography color="text.secondary" variant="body2">
588
+ Light theme item
589
+ </Typography>
590
+ }
591
+ />
592
+ </ListItem>
593
+ </Box>
594
+ )}
595
+ data-testid="light-theme-list"
596
+ />
597
+ </Paper>
598
+
599
+ {/* Dark theme simulation */}
600
+ <Paper sx={{ width: 300, height: 250, bgcolor: '#1e1e1e', color: 'white' }}>
601
+ <Typography variant="caption" sx={{ p: 1, display: 'block', color: 'white' }}>
602
+ Dark Theme
603
+ </Typography>
604
+ <VirtualList
605
+ items={items}
606
+ variant="fixed"
607
+ height={220}
608
+ itemHeight={55}
609
+ renderItem={({ item, style }) => (
610
+ <Box key={item.id} style={style}>
611
+ <ListItem sx={{ borderBottom: '1px solid rgba(255,255,255,0.12)', color: 'white' }}>
612
+ <ListItemAvatar>
613
+ <Avatar src={item.data.avatar} />
614
+ </ListItemAvatar>
615
+ <ListItemText
616
+ primary={<Typography sx={{ color: 'white' }}>{item.data.name}</Typography>}
617
+ secondary={
618
+ <Typography sx={{ color: 'rgba(255,255,255,0.7)' }} variant="body2">
619
+ Dark theme item
620
+ </Typography>
621
+ }
622
+ />
623
+ </ListItem>
624
+ </Box>
625
+ )}
626
+ data-testid="dark-theme-list"
627
+ />
628
+ </Paper>
629
+ </Box>
630
+ );
631
+ },
632
+ play: async ({ canvasElement }) => {
633
+ const canvas = within(canvasElement);
634
+
635
+ // Test light theme list
636
+ const lightList = canvas.getByTestId('light-theme-list');
637
+ await expect(lightList).toBeInTheDocument();
638
+
639
+ // Test dark theme list
640
+ const darkList = canvas.getByTestId('dark-theme-list');
641
+ await expect(darkList).toBeInTheDocument();
642
+
643
+ // Verify both lists render items
644
+ await waitFor(
645
+ () => {
646
+ expect(lightList.children.length).toBeGreaterThan(0);
647
+ },
648
+ { timeout: 2000 },
649
+ );
650
+
651
+ await waitFor(
652
+ () => {
653
+ expect(darkList.children.length).toBeGreaterThan(0);
654
+ },
655
+ { timeout: 2000 },
656
+ );
657
+ },
658
+ };
659
+
660
+ // Visual States Tests
661
+ export const VisualStates: Story = {
662
+ render: () => {
663
+ const emptyItems: VirtualListItem[] = [];
664
+
665
+ return (
666
+ <Box sx={{ display: 'flex', gap: 2, flexWrap: 'wrap' }}>
667
+ {/* Loading state */}
668
+ <Paper sx={{ width: 250, height: 200 }}>
669
+ <Typography variant="caption" sx={{ p: 1, display: 'block' }}>
670
+ Loading State
671
+ </Typography>
672
+ <VirtualList
673
+ items={Array.from({ length: 5 }, (_, i) => ({ id: i }))}
674
+ variant="fixed"
675
+ height={170}
676
+ itemHeight={40}
677
+ renderItem={({ style, index }) => (
678
+ <Box key={index} style={style} sx={{ p: 1 }}>
679
+ <Skeleton variant="rectangular" width="100%" height={30} />
680
+ </Box>
681
+ )}
682
+ data-testid="loading-list"
683
+ />
684
+ </Paper>
685
+
686
+ {/* Empty state */}
687
+ <Paper sx={{ width: 250, height: 200 }}>
688
+ <Typography variant="caption" sx={{ p: 1, display: 'block' }}>
689
+ Empty State
690
+ </Typography>
691
+ <VirtualList
692
+ items={emptyItems}
693
+ variant="fixed"
694
+ height={170}
695
+ itemHeight={40}
696
+ renderItem={({ item, style }) => (
697
+ <Box key={item.id} style={style}>
698
+ <ListItem>
699
+ <ListItemText primary={item.data?.name} />
700
+ </ListItem>
701
+ </Box>
702
+ )}
703
+ data-testid="empty-list"
704
+ />
705
+ {emptyItems.length === 0 && (
706
+ <Box sx={{ p: 2, textAlign: 'center' }}>
707
+ <Typography variant="body2" color="text.secondary">
708
+ No items to display
709
+ </Typography>
710
+ </Box>
711
+ )}
712
+ </Paper>
713
+
714
+ {/* Error state */}
715
+ <Paper sx={{ width: 250, height: 200 }}>
716
+ <Typography variant="caption" sx={{ p: 1, display: 'block' }}>
717
+ Error State
718
+ </Typography>
719
+ <Alert severity="error" sx={{ m: 1 }}>
720
+ Failed to load data
721
+ </Alert>
722
+ </Paper>
723
+ </Box>
724
+ );
725
+ },
726
+ play: async ({ canvasElement }) => {
727
+ const canvas = within(canvasElement);
728
+
729
+ // Test loading state
730
+ const loadingList = canvas.getByTestId('loading-list');
731
+ await expect(loadingList).toBeInTheDocument();
732
+
733
+ // Test skeleton loaders are present (wait for them to render)
734
+ await waitFor(
735
+ () => {
736
+ const skeletons = canvasElement.querySelectorAll('.MuiSkeleton-root');
737
+ expect(skeletons.length).toBeGreaterThan(0);
738
+ },
739
+ { timeout: 2000 },
740
+ );
741
+
742
+ // Test empty state
743
+ const emptyList = canvas.getByTestId('empty-list');
744
+ await expect(emptyList).toBeInTheDocument();
745
+
746
+ // Test empty message
747
+ const emptyMessage = canvas.getByText('No items to display');
748
+ await expect(emptyMessage).toBeInTheDocument();
749
+
750
+ // Test error state
751
+ const errorAlert = canvas.getByRole('alert');
752
+ await expect(errorAlert).toBeInTheDocument();
753
+ },
754
+ };
755
+
756
+ // Performance Tests
757
+ export const Performance: Story = {
758
+ render: () => {
759
+ const largeDataset = generateItems(10000);
760
+
761
+ return (
762
+ <Paper sx={{ width: 400, height: 400 }}>
763
+ <Box sx={{ p: 2, borderBottom: '1px solid', borderColor: 'divider' }}>
764
+ <Typography variant="h6">Performance Test</Typography>
765
+ <Typography variant="body2" color="text.secondary">
766
+ 10,000 items - Virtual scrolling
767
+ </Typography>
768
+ </Box>
769
+ <VirtualList
770
+ items={largeDataset}
771
+ variant="fixed"
772
+ height={350}
773
+ itemHeight={50}
774
+ overscan={10}
775
+ renderItem={({ item, index, style }) => {
776
+ // Simulate some computation
777
+ const computedValue = Math.sin(index) * 100;
778
+
779
+ return (
780
+ <Box key={item.id} style={style}>
781
+ <ListItem>
782
+ <ListItemAvatar>
783
+ <Avatar>{index + 1}</Avatar>
784
+ </ListItemAvatar>
785
+ <ListItemText
786
+ primary={`Item ${index + 1}`}
787
+ secondary={`Computed: ${computedValue.toFixed(2)}`}
788
+ />
789
+ </ListItem>
790
+ </Box>
791
+ );
792
+ }}
793
+ data-testid="performance-list"
794
+ />
795
+ </Paper>
796
+ );
797
+ },
798
+ play: async ({ canvasElement }) => {
799
+ const canvas = within(canvasElement);
800
+ const performanceList = canvas.getByTestId('performance-list');
801
+
802
+ // Test that performance list renders correctly
803
+ await expect(performanceList).toBeInTheDocument();
804
+
805
+ // Test rapid scrolling performance
806
+ // Perform scrolling with proper event simulation
807
+ fireEvent.scroll(performanceList, { target: { scrollTop: 500 } });
808
+ await waitFor(
809
+ () => {
810
+ expect(performanceList.scrollTop).toBeGreaterThan(0);
811
+ },
812
+ { timeout: 2000 },
813
+ );
814
+
815
+ // Test multiple scroll events
816
+ for (let i = 1; i <= 3; i++) {
817
+ fireEvent.scroll(performanceList, { target: { scrollTop: i * 200 } });
818
+ await new Promise<void>((resolve) => {
819
+ setTimeout(resolve, 50);
820
+ });
821
+ }
822
+
823
+ // Verify list is still responsive
824
+ await expect(performanceList).toBeInTheDocument();
825
+ await waitFor(
826
+ () => {
827
+ expect(performanceList.scrollTop).toBeGreaterThan(0);
828
+ },
829
+ { timeout: 1000 },
830
+ );
831
+ },
832
+ };
833
+
834
+ // Edge Cases Tests
835
+ export const EdgeCases: Story = {
836
+ render: () => {
837
+ const singleItem = generateItems(1);
838
+ const variableItems = generateVariableItems(20);
839
+ const emptyItems: VirtualListItem[] = [];
840
+
841
+ return (
842
+ <Box sx={{ display: 'flex', gap: 2, flexWrap: 'wrap' }}>
843
+ {/* Single item */}
844
+ <Paper sx={{ width: 200, height: 150 }}>
845
+ <Typography variant="caption" sx={{ p: 1, display: 'block' }}>
846
+ Single Item
847
+ </Typography>
848
+ <VirtualList
849
+ items={singleItem}
850
+ variant="fixed"
851
+ height={120}
852
+ itemHeight={50}
853
+ renderItem={SimpleItemRenderer}
854
+ data-testid="single-item-list"
855
+ />
856
+ </Paper>
857
+
858
+ {/* Variable heights */}
859
+ <Paper sx={{ width: 250, height: 150 }}>
860
+ <Typography variant="caption" sx={{ p: 1, display: 'block' }}>
861
+ Variable Heights
862
+ </Typography>
863
+ <VirtualList
864
+ items={variableItems}
865
+ variant="variable"
866
+ height={120}
867
+ estimatedItemHeight={80}
868
+ renderItem={({ item, style }) => (
869
+ <Box key={item.id} style={style}>
870
+ <ListItem sx={{ alignItems: 'flex-start' }}>
871
+ <ListItemAvatar>
872
+ <Avatar src={item.data.avatar} />
873
+ </ListItemAvatar>
874
+ <ListItemText primary={item.data.name} secondary={item.data.description} />
875
+ </ListItem>
876
+ </Box>
877
+ )}
878
+ data-testid="variable-height-list"
879
+ />
880
+ </Paper>
881
+
882
+ {/* Zero items */}
883
+ <Paper sx={{ width: 200, height: 150 }}>
884
+ <Typography variant="caption" sx={{ p: 1, display: 'block' }}>
885
+ Zero Items
886
+ </Typography>
887
+ <VirtualList
888
+ items={emptyItems}
889
+ variant="fixed"
890
+ height={120}
891
+ itemHeight={50}
892
+ renderItem={SimpleItemRenderer}
893
+ data-testid="zero-items-list"
894
+ />
895
+ </Paper>
896
+ </Box>
897
+ );
898
+ },
899
+ play: async ({ canvasElement }) => {
900
+ const canvas = within(canvasElement);
901
+
902
+ // Test single item
903
+ const singleItemList = canvas.getByTestId('single-item-list');
904
+ await expect(singleItemList).toBeInTheDocument();
905
+
906
+ // Wait for item to render
907
+ await waitFor(
908
+ () => {
909
+ expect(singleItemList.children.length).toBeGreaterThan(0);
910
+ },
911
+ { timeout: 2000 },
912
+ );
913
+
914
+ // Test variable heights
915
+ const variableHeightList = canvas.getByTestId('variable-height-list');
916
+ await expect(variableHeightList).toBeInTheDocument();
917
+
918
+ // Wait for items to render before testing scroll
919
+ await waitFor(
920
+ () => {
921
+ expect(variableHeightList.children.length).toBeGreaterThan(0);
922
+ },
923
+ { timeout: 2000 },
924
+ );
925
+
926
+ // Test scrolling with variable heights
927
+ fireEvent.scroll(variableHeightList, { target: { scrollTop: 100 } });
928
+ await waitFor(
929
+ () => {
930
+ expect(variableHeightList.scrollTop).toBeGreaterThan(0);
931
+ },
932
+ { timeout: 1000 },
933
+ );
934
+
935
+ // Test zero items
936
+ const zeroItemsList = canvas.getByTestId('zero-items-list');
937
+ await expect(zeroItemsList).toBeInTheDocument();
938
+
939
+ // Zero items list should have minimal or no child elements (it might have a container div)
940
+ // The inner container for virtualization might still be present even with no items
941
+ expect(zeroItemsList.children.length).toBeLessThanOrEqual(1);
942
+ },
943
+ };
944
+
945
+ // Integration Tests
946
+ export const Integration: Story = {
947
+ render: () => {
948
+ const items = generateItems(100);
949
+ const gridItems = generateItems(50);
950
+
951
+ return (
952
+ <Box sx={{ display: 'flex', gap: 2 }}>
953
+ {/* List + Grid Integration */}
954
+ <Paper sx={{ width: 300, height: 400 }}>
955
+ <Typography variant="h6" sx={{ p: 2 }}>
956
+ List View
957
+ </Typography>
958
+ <VirtualList
959
+ items={items}
960
+ variant="fixed"
961
+ height={350}
962
+ itemHeight={60}
963
+ renderItem={({ item, index, style }) => (
964
+ <Box key={item.id} style={style}>
965
+ <ListItem
966
+ button
967
+ onClick={() => {
968
+ // Integration with external handlers
969
+ // eslint-disable-next-line no-console
970
+ console.log('Clicked item:', item.id);
971
+ }}
972
+ >
973
+ <ListItemAvatar>
974
+ <Avatar src={item.data.avatar} />
975
+ </ListItemAvatar>
976
+ <ListItemText primary={item.data.name} secondary={`List item ${index + 1}`} />
977
+ </ListItem>
978
+ </Box>
979
+ )}
980
+ data-testid="integration-list"
981
+ />
982
+ </Paper>
983
+
984
+ <Paper sx={{ width: 400, height: 400 }}>
985
+ <Typography variant="h6" sx={{ p: 2 }}>
986
+ Grid View
987
+ </Typography>
988
+ <VirtualGrid
989
+ items={gridItems}
990
+ height={350}
991
+ width={400}
992
+ columnCount={3}
993
+ rowHeight={100}
994
+ gap={8}
995
+ renderItem={({ item, style }) => (
996
+ <Box
997
+ key={item.id}
998
+ style={style}
999
+ sx={{
1000
+ bgcolor: 'primary.light',
1001
+ borderRadius: 2,
1002
+ display: 'flex',
1003
+ alignItems: 'center',
1004
+ justifyContent: 'center',
1005
+ cursor: 'pointer',
1006
+ '&:hover': {
1007
+ bgcolor: 'primary.main',
1008
+ },
1009
+ }}
1010
+ onClick={() => {
1011
+ // Integration with external handlers
1012
+ // eslint-disable-next-line no-console
1013
+ console.log('Clicked grid item:', item.id);
1014
+ }}
1015
+ >
1016
+ <Typography variant="body2" color="white">
1017
+ #{item.id + 1}
1018
+ </Typography>
1019
+ </Box>
1020
+ )}
1021
+ data-testid="integration-grid"
1022
+ />
1023
+ </Paper>
1024
+ </Box>
1025
+ );
1026
+ },
1027
+ play: async ({ canvasElement }) => {
1028
+ const canvas = within(canvasElement);
1029
+
1030
+ // Test list integration
1031
+ const integrationList = canvas.getByTestId('integration-list');
1032
+ await expect(integrationList).toBeInTheDocument();
1033
+
1034
+ // Test grid integration
1035
+ const integrationGrid = canvas.getByTestId('integration-grid');
1036
+ await expect(integrationGrid).toBeInTheDocument();
1037
+
1038
+ // Wait for items to render
1039
+ await waitFor(
1040
+ () => {
1041
+ expect(integrationList.children.length).toBeGreaterThan(0);
1042
+ },
1043
+ { timeout: 2000 },
1044
+ );
1045
+
1046
+ await waitFor(
1047
+ () => {
1048
+ expect(integrationGrid.children.length).toBeGreaterThan(0);
1049
+ },
1050
+ { timeout: 2000 },
1051
+ );
1052
+
1053
+ // Test clicking on first visible list item
1054
+ const firstListItem = integrationList.querySelector('div[style*="position"]');
1055
+ if (firstListItem) {
1056
+ await userEvent.click(firstListItem);
1057
+ }
1058
+
1059
+ // Test clicking on first visible grid item
1060
+ const firstGridItem = integrationGrid.querySelector('div[style*="position"]');
1061
+ if (firstGridItem) {
1062
+ await userEvent.click(firstGridItem);
1063
+ }
1064
+
1065
+ // Test that both components work independently
1066
+ fireEvent.scroll(integrationList, { target: { scrollTop: 200 } });
1067
+ fireEvent.scroll(integrationGrid, { target: { scrollTop: 200 } });
1068
+
1069
+ await waitFor(() => {
1070
+ expect(integrationList.scrollTop).toBeGreaterThan(0);
1071
+ expect(integrationGrid.scrollTop).toBeGreaterThan(0);
1072
+ });
1073
+ },
1074
+ };