@okta/odyssey-react-mui 1.28.1 → 1.29.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 (326) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/Breadcrumbs.js +1 -0
  3. package/dist/Breadcrumbs.js.map +1 -1
  4. package/dist/Buttons/MenuItem.js +1 -0
  5. package/dist/Buttons/MenuItem.js.map +1 -1
  6. package/dist/Checkbox.js +62 -35
  7. package/dist/Checkbox.js.map +1 -1
  8. package/dist/DataTable/reorderDataRowsLocally.js.map +1 -1
  9. package/dist/DataTable/useRowReordering.js.map +1 -1
  10. package/dist/HtmlProps.js.map +1 -1
  11. package/dist/Pagination/Pagination.js +2 -1
  12. package/dist/Pagination/Pagination.js.map +1 -1
  13. package/dist/Radio.js +65 -38
  14. package/dist/Radio.js.map +1 -1
  15. package/dist/Typography.js +20 -0
  16. package/dist/Typography.js.map +1 -1
  17. package/dist/index.scss +1 -1
  18. package/dist/labs/DataFilters.js +9 -5
  19. package/dist/labs/DataFilters.js.map +1 -1
  20. package/dist/labs/DataTable.js +7 -7
  21. package/dist/labs/DataTable.js.map +1 -1
  22. package/dist/labs/DataView/BulkActionsMenu.js.map +1 -1
  23. package/dist/labs/DataView/CardLayoutContent.js +6 -5
  24. package/dist/labs/DataView/CardLayoutContent.js.map +1 -1
  25. package/dist/labs/DataView/DataCard.js +1 -0
  26. package/dist/labs/DataView/DataCard.js.map +1 -1
  27. package/dist/labs/DataView/DataTable.js.map +1 -1
  28. package/dist/labs/DataView/DataView.js +2 -2
  29. package/dist/labs/DataView/DataView.js.map +1 -1
  30. package/dist/labs/DataView/DetailPanel.js.map +1 -1
  31. package/dist/labs/DataView/RowActions.js.map +1 -1
  32. package/dist/labs/DataView/TableLayoutContent.js +1 -1
  33. package/dist/labs/DataView/TableLayoutContent.js.map +1 -1
  34. package/dist/labs/DataView/TableSettings.js.map +1 -1
  35. package/dist/labs/DataView/componentTypes.js.map +1 -1
  36. package/dist/labs/DataView/dataTypes.js.map +1 -1
  37. package/dist/labs/DataView/fetchData.js.map +1 -1
  38. package/dist/labs/DataView/testSupportData.js +201 -0
  39. package/dist/labs/DataView/testSupportData.js.map +1 -0
  40. package/dist/labs/DataView/useFilterConversion.js.map +1 -1
  41. package/dist/labs/{DateField.js → DatePickers/DateField.js} +1 -1
  42. package/dist/labs/DatePickers/DateField.js.map +1 -0
  43. package/dist/labs/DatePickers/DateFieldActionBar.js +56 -0
  44. package/dist/labs/DatePickers/DateFieldActionBar.js.map +1 -0
  45. package/dist/labs/DatePickers/DateFieldLocalizationProvider.js +32 -0
  46. package/dist/labs/DatePickers/DateFieldLocalizationProvider.js.map +1 -0
  47. package/dist/labs/{DatePicker.js → DatePickers/DatePicker.js} +30 -73
  48. package/dist/labs/DatePickers/DatePicker.js.map +1 -0
  49. package/dist/labs/DatePickers/DatePicker.types.d.js.map +1 -0
  50. package/dist/labs/DatePickers/DateTimeField.js +166 -0
  51. package/dist/labs/DatePickers/DateTimeField.js.map +1 -0
  52. package/dist/labs/DatePickers/DateTimePicker.js +233 -0
  53. package/dist/labs/DatePickers/DateTimePicker.js.map +1 -0
  54. package/dist/labs/{datePickerTheme.js → DatePickers/datePickerTheme.js} +2 -2
  55. package/dist/labs/DatePickers/datePickerTheme.js.map +1 -0
  56. package/dist/labs/DatePickers/dateTimePickerTheme.js +230 -0
  57. package/dist/labs/DatePickers/dateTimePickerTheme.js.map +1 -0
  58. package/dist/labs/DatePickers/index.js +15 -0
  59. package/dist/labs/DatePickers/index.js.map +1 -0
  60. package/dist/labs/DatePickers/useDateFieldsTranslations.js.map +1 -0
  61. package/dist/labs/{useOdysseyDateFields.js → DatePickers/useOdysseyDateFields.js} +36 -3
  62. package/dist/labs/DatePickers/useOdysseyDateFields.js.map +1 -0
  63. package/dist/labs/PageTemplate.js +1 -1
  64. package/dist/labs/PageTemplate.js.map +1 -1
  65. package/dist/labs/SideNav/SideNav.js +40 -34
  66. package/dist/labs/SideNav/SideNav.js.map +1 -1
  67. package/dist/labs/SideNav/SideNavHeader.js +6 -4
  68. package/dist/labs/SideNav/SideNavHeader.js.map +1 -1
  69. package/dist/labs/SideNav/SideNavItemContent.js +11 -11
  70. package/dist/labs/SideNav/SideNavItemContent.js.map +1 -1
  71. package/dist/labs/SideNav/SideNavToggleButton.js +1 -1
  72. package/dist/labs/SideNav/SideNavToggleButton.js.map +1 -1
  73. package/dist/labs/SideNav/types.js.map +1 -1
  74. package/dist/labs/TimeZonePicker.js.map +1 -1
  75. package/dist/labs/index.js +1 -3
  76. package/dist/labs/index.js.map +1 -1
  77. package/dist/properties/ts/odyssey-react-mui.js +2 -0
  78. package/dist/properties/ts/odyssey-react-mui.js.map +1 -1
  79. package/dist/src/Breadcrumbs.d.ts.map +1 -1
  80. package/dist/src/Buttons/MenuItem.d.ts.map +1 -1
  81. package/dist/src/Checkbox.d.ts.map +1 -1
  82. package/dist/src/DataTable/reorderDataRowsLocally.d.ts +3 -3
  83. package/dist/src/DataTable/reorderDataRowsLocally.d.ts.map +1 -1
  84. package/dist/src/DataTable/useRowReordering.d.ts +10 -10
  85. package/dist/src/DataTable/useRowReordering.d.ts.map +1 -1
  86. package/dist/src/HtmlProps.d.ts +27 -0
  87. package/dist/src/HtmlProps.d.ts.map +1 -1
  88. package/dist/src/OdysseyTranslationProvider.d.ts +1 -1
  89. package/dist/src/OdysseyTranslationProvider.d.ts.map +1 -1
  90. package/dist/src/Radio.d.ts +1 -1
  91. package/dist/src/Radio.d.ts.map +1 -1
  92. package/dist/src/Typography.d.ts +11 -11
  93. package/dist/src/Typography.d.ts.map +1 -1
  94. package/dist/src/labs/DataFilters.d.ts.map +1 -1
  95. package/dist/src/labs/DataTable.d.ts +11 -11
  96. package/dist/src/labs/DataTable.d.ts.map +1 -1
  97. package/dist/src/labs/DataView/BulkActionsMenu.d.ts +3 -3
  98. package/dist/src/labs/DataView/BulkActionsMenu.d.ts.map +1 -1
  99. package/dist/src/labs/DataView/CardLayoutContent.d.ts +18 -15
  100. package/dist/src/labs/DataView/CardLayoutContent.d.ts.map +1 -1
  101. package/dist/src/labs/DataView/DataCard.d.ts +7 -4
  102. package/dist/src/labs/DataView/DataCard.d.ts.map +1 -1
  103. package/dist/src/labs/DataView/DataTable.d.ts +6 -2
  104. package/dist/src/labs/DataView/DataTable.d.ts.map +1 -1
  105. package/dist/src/labs/DataView/DataView.d.ts +6 -2
  106. package/dist/src/labs/DataView/DataView.d.ts.map +1 -1
  107. package/dist/src/labs/DataView/DetailPanel.d.ts +5 -5
  108. package/dist/src/labs/DataView/DetailPanel.d.ts.map +1 -1
  109. package/dist/src/labs/DataView/RowActions.d.ts +3 -3
  110. package/dist/src/labs/DataView/RowActions.d.ts.map +1 -1
  111. package/dist/src/labs/DataView/TableLayoutContent.d.ts +18 -15
  112. package/dist/src/labs/DataView/TableLayoutContent.d.ts.map +1 -1
  113. package/dist/src/labs/DataView/TableSettings.d.ts +7 -3
  114. package/dist/src/labs/DataView/TableSettings.d.ts.map +1 -1
  115. package/dist/src/labs/DataView/componentTypes.d.ts +17 -17
  116. package/dist/src/labs/DataView/componentTypes.d.ts.map +1 -1
  117. package/dist/src/labs/DataView/dataTypes.d.ts +6 -6
  118. package/dist/src/labs/DataView/dataTypes.d.ts.map +1 -1
  119. package/dist/src/labs/DataView/fetchData.d.ts +6 -6
  120. package/dist/src/labs/DataView/fetchData.d.ts.map +1 -1
  121. package/dist/src/labs/DataView/testSupportData.d.ts +33 -0
  122. package/dist/src/labs/DataView/testSupportData.d.ts.map +1 -0
  123. package/dist/src/labs/DataView/useFilterConversion.d.ts +5 -4
  124. package/dist/src/labs/DataView/useFilterConversion.d.ts.map +1 -1
  125. package/dist/src/labs/{DateField.d.ts → DatePickers/DateField.d.ts} +1 -1
  126. package/dist/src/labs/DatePickers/DateField.d.ts.map +1 -0
  127. package/dist/src/labs/DatePickers/DateFieldActionBar.d.ts +15 -0
  128. package/dist/src/labs/DatePickers/DateFieldActionBar.d.ts.map +1 -0
  129. package/dist/src/labs/DatePickers/DateFieldLocalizationProvider.d.ts +20 -0
  130. package/dist/src/labs/DatePickers/DateFieldLocalizationProvider.d.ts.map +1 -0
  131. package/dist/src/labs/DatePickers/DatePicker.d.ts +17 -0
  132. package/dist/src/labs/DatePickers/DatePicker.d.ts.map +1 -0
  133. package/dist/src/labs/DatePickers/DateTimeField.d.ts +20 -0
  134. package/dist/src/labs/DatePickers/DateTimeField.d.ts.map +1 -0
  135. package/dist/src/labs/DatePickers/DateTimePicker.d.ts +17 -0
  136. package/dist/src/labs/DatePickers/DateTimePicker.d.ts.map +1 -0
  137. package/dist/src/labs/DatePickers/datePickerTheme.d.ts +22 -0
  138. package/dist/src/labs/DatePickers/datePickerTheme.d.ts.map +1 -0
  139. package/dist/src/labs/{datePickerTheme.d.ts → DatePickers/dateTimePickerTheme.d.ts} +2 -2
  140. package/dist/src/labs/DatePickers/dateTimePickerTheme.d.ts.map +1 -0
  141. package/dist/src/labs/DatePickers/index.d.ts +15 -0
  142. package/dist/src/labs/DatePickers/index.d.ts.map +1 -0
  143. package/dist/src/labs/DatePickers/useDateFieldsTranslations.d.ts.map +1 -0
  144. package/dist/src/labs/{useOdysseyDateFields.d.ts → DatePickers/useOdysseyDateFields.d.ts} +49 -6
  145. package/dist/src/labs/DatePickers/useOdysseyDateFields.d.ts.map +1 -0
  146. package/dist/src/labs/SideNav/SideNav.d.ts.map +1 -1
  147. package/dist/src/labs/SideNav/SideNavHeader.d.ts.map +1 -1
  148. package/dist/src/labs/SideNav/SideNavItemContent.d.ts +1 -1
  149. package/dist/src/labs/SideNav/SideNavItemContent.d.ts.map +1 -1
  150. package/dist/src/labs/SideNav/types.d.ts +2 -2
  151. package/dist/src/labs/SideNav/types.d.ts.map +1 -1
  152. package/dist/src/labs/TimeZonePicker.d.ts +4 -1
  153. package/dist/src/labs/TimeZonePicker.d.ts.map +1 -1
  154. package/dist/src/labs/index.d.ts +1 -3
  155. package/dist/src/labs/index.d.ts.map +1 -1
  156. package/dist/src/properties/ts/odyssey-react-mui.d.ts +2 -0
  157. package/dist/src/properties/ts/odyssey-react-mui.d.ts.map +1 -1
  158. package/dist/src/theme/components.d.ts.map +1 -1
  159. package/dist/src/theme/mixins.d.ts.map +1 -1
  160. package/dist/src/theme/mixins.types.d.ts +2 -0
  161. package/dist/src/theme/mixins.types.d.ts.map +1 -1
  162. package/dist/src/{labs → ui-shell}/UiShell/UiShell.d.ts +2 -2
  163. package/dist/src/ui-shell/UiShell/UiShell.d.ts.map +1 -0
  164. package/dist/src/{labs → ui-shell}/UiShell/UiShellContent.d.ts +12 -8
  165. package/dist/src/ui-shell/UiShell/UiShellContent.d.ts.map +1 -0
  166. package/dist/src/ui-shell/UiShell/bufferLatest.d.ts.map +1 -0
  167. package/dist/src/ui-shell/UiShell/createMessageBus.d.ts.map +1 -0
  168. package/dist/src/ui-shell/UiShell/createStore.d.ts.map +1 -0
  169. package/dist/src/ui-shell/UiShell/index.d.ts.map +1 -0
  170. package/dist/src/{labs → ui-shell}/UiShell/renderUiShell.d.ts +3 -4
  171. package/dist/src/ui-shell/UiShell/renderUiShell.d.ts.map +1 -0
  172. package/dist/src/{labs → ui-shell}/UiShell/useHasUiShell.d.ts +1 -0
  173. package/dist/src/ui-shell/UiShell/useHasUiShell.d.ts.map +1 -0
  174. package/dist/src/ui-shell/UiShell/useScrollState.d.ts.map +1 -0
  175. package/dist/src/ui-shell/index.d.ts +14 -0
  176. package/dist/src/ui-shell/index.d.ts.map +1 -0
  177. package/dist/src/{web-component → ui-shell}/renderReactInWebComponent.d.ts +3 -23
  178. package/dist/src/ui-shell/renderReactInWebComponent.d.ts.map +1 -0
  179. package/dist/src/web-component/index.d.ts +0 -1
  180. package/dist/src/web-component/index.d.ts.map +1 -1
  181. package/dist/src/web-component/shadow-dom.d.ts +23 -2
  182. package/dist/src/web-component/shadow-dom.d.ts.map +1 -1
  183. package/dist/theme/components.js +38 -4
  184. package/dist/theme/components.js.map +1 -1
  185. package/dist/theme/mixins.js +2 -1
  186. package/dist/theme/mixins.js.map +1 -1
  187. package/dist/theme/mixins.types.js.map +1 -1
  188. package/dist/tsconfig.production.tsbuildinfo +1 -1
  189. package/dist/{labs → ui-shell}/UiShell/UiShell.js +2 -0
  190. package/dist/ui-shell/UiShell/UiShell.js.map +1 -0
  191. package/dist/{labs → ui-shell}/UiShell/UiShellContent.js +19 -11
  192. package/dist/ui-shell/UiShell/UiShellContent.js.map +1 -0
  193. package/dist/ui-shell/UiShell/bufferLatest.js.map +1 -0
  194. package/dist/ui-shell/UiShell/createMessageBus.js.map +1 -0
  195. package/dist/ui-shell/UiShell/createStore.js.map +1 -0
  196. package/dist/ui-shell/UiShell/index.js.map +1 -0
  197. package/dist/{labs → ui-shell}/UiShell/renderUiShell.js +4 -2
  198. package/dist/ui-shell/UiShell/renderUiShell.js.map +1 -0
  199. package/dist/{labs → ui-shell}/UiShell/useHasUiShell.js +1 -1
  200. package/dist/ui-shell/UiShell/useHasUiShell.js.map +1 -0
  201. package/dist/ui-shell/UiShell/useScrollState.js.map +1 -0
  202. package/dist/ui-shell/index.js +14 -0
  203. package/dist/ui-shell/index.js.map +1 -0
  204. package/dist/{web-component → ui-shell}/renderReactInWebComponent.js +7 -17
  205. package/dist/ui-shell/renderReactInWebComponent.js.map +1 -0
  206. package/dist/web-component/index.js +0 -1
  207. package/dist/web-component/index.js.map +1 -1
  208. package/dist/web-component/shadow-dom.js +12 -2
  209. package/dist/web-component/shadow-dom.js.map +1 -1
  210. package/package.json +10 -3
  211. package/src/Breadcrumbs.tsx +5 -1
  212. package/src/Buttons/MenuItem.tsx +1 -0
  213. package/src/Checkbox.tsx +86 -44
  214. package/src/DataTable/reorderDataRowsLocally.tsx +3 -3
  215. package/src/DataTable/useRowReordering.tsx +16 -23
  216. package/src/HtmlProps.ts +27 -0
  217. package/src/Pagination/Pagination.tsx +2 -2
  218. package/src/Radio.tsx +78 -39
  219. package/src/Typography.tsx +26 -1
  220. package/src/labs/DataFilters.tsx +7 -3
  221. package/src/labs/DataTable.tsx +41 -33
  222. package/src/labs/DataView/BulkActionsMenu.tsx +4 -4
  223. package/src/labs/DataView/CardLayoutContent.tsx +34 -28
  224. package/src/labs/DataView/DataCard.tsx +13 -6
  225. package/src/labs/DataView/DataTable.tsx +11 -4
  226. package/src/labs/DataView/DataView.test.tsx +1012 -87
  227. package/src/labs/DataView/DataView.tsx +18 -11
  228. package/src/labs/DataView/DetailPanel.tsx +4 -4
  229. package/src/labs/DataView/RowActions.tsx +4 -4
  230. package/src/labs/DataView/TableLayoutContent.tsx +30 -24
  231. package/src/labs/DataView/TableSettings.tsx +12 -6
  232. package/src/labs/DataView/componentTypes.ts +17 -17
  233. package/src/labs/DataView/dataTypes.ts +14 -8
  234. package/src/labs/DataView/fetchData.ts +9 -7
  235. package/src/labs/DataView/testSupportData.tsx +301 -0
  236. package/src/labs/DataView/useFilterConversion.ts +8 -8
  237. package/src/labs/{DateField.tsx → DatePickers/DateField.tsx} +2 -2
  238. package/src/labs/DatePickers/DateFieldActionBar.tsx +65 -0
  239. package/src/labs/DatePickers/DateFieldLocalizationProvider.tsx +46 -0
  240. package/src/labs/{DatePicker.tsx → DatePickers/DatePicker.tsx} +31 -136
  241. package/src/labs/DatePickers/DateTimeField.tsx +271 -0
  242. package/src/labs/DatePickers/DateTimePicker.test.tsx +66 -0
  243. package/src/labs/DatePickers/DateTimePicker.tsx +303 -0
  244. package/src/labs/{datePickerTheme.tsx → DatePickers/datePickerTheme.tsx} +2 -2
  245. package/src/labs/DatePickers/dateTimePickerTheme.ts +213 -0
  246. package/src/labs/DatePickers/index.ts +15 -0
  247. package/src/labs/{useOdysseyDateFields.ts → DatePickers/useOdysseyDateFields.ts} +112 -10
  248. package/src/labs/PageTemplate.tsx +1 -1
  249. package/src/labs/SideNav/SideNav.tsx +38 -39
  250. package/src/labs/SideNav/SideNavHeader.tsx +6 -4
  251. package/src/labs/SideNav/SideNavItemContent.tsx +21 -18
  252. package/src/labs/SideNav/SideNavToggleButton.tsx +1 -1
  253. package/src/labs/SideNav/types.ts +2 -2
  254. package/src/labs/TimeZonePicker.tsx +5 -1
  255. package/src/labs/index.ts +2 -3
  256. package/src/properties/odyssey-react-mui.properties +2 -0
  257. package/src/properties/ts/odyssey-react-mui.ts +1 -1
  258. package/src/theme/components.tsx +45 -4
  259. package/src/theme/mixins.ts +1 -0
  260. package/src/theme/mixins.types.ts +2 -0
  261. package/src/{labs → ui-shell}/UiShell/UiShell.tsx +3 -0
  262. package/src/{labs → ui-shell}/UiShell/UiShellContent.tsx +60 -31
  263. package/src/{labs → ui-shell}/UiShell/renderUiShell.test.tsx +16 -22
  264. package/src/{labs → ui-shell}/UiShell/renderUiShell.tsx +7 -4
  265. package/src/{labs → ui-shell}/UiShell/useHasUiShell.ts +1 -1
  266. package/src/ui-shell/index.ts +14 -0
  267. package/src/{web-component → ui-shell}/renderReactInWebComponent.test.tsx +1 -1
  268. package/src/{web-component → ui-shell}/renderReactInWebComponent.ts +9 -45
  269. package/src/web-component/index.ts +0 -1
  270. package/src/web-component/shadow-dom.ts +36 -3
  271. package/dist/labs/DateField.js.map +0 -1
  272. package/dist/labs/DatePicker.js.map +0 -1
  273. package/dist/labs/DatePicker.types.d.js.map +0 -1
  274. package/dist/labs/UiShell/UiShell.js.map +0 -1
  275. package/dist/labs/UiShell/UiShellContent.js.map +0 -1
  276. package/dist/labs/UiShell/bufferLatest.js.map +0 -1
  277. package/dist/labs/UiShell/createMessageBus.js.map +0 -1
  278. package/dist/labs/UiShell/createStore.js.map +0 -1
  279. package/dist/labs/UiShell/index.js.map +0 -1
  280. package/dist/labs/UiShell/renderUiShell.js.map +0 -1
  281. package/dist/labs/UiShell/useHasUiShell.js.map +0 -1
  282. package/dist/labs/UiShell/useScrollState.js.map +0 -1
  283. package/dist/labs/datePickerTheme.js.map +0 -1
  284. package/dist/labs/useDateFieldsTranslations.js.map +0 -1
  285. package/dist/labs/useOdysseyDateFields.js.map +0 -1
  286. package/dist/src/labs/DateField.d.ts.map +0 -1
  287. package/dist/src/labs/DatePicker.d.ts +0 -47
  288. package/dist/src/labs/DatePicker.d.ts.map +0 -1
  289. package/dist/src/labs/UiShell/UiShell.d.ts.map +0 -1
  290. package/dist/src/labs/UiShell/UiShellContent.d.ts.map +0 -1
  291. package/dist/src/labs/UiShell/bufferLatest.d.ts.map +0 -1
  292. package/dist/src/labs/UiShell/createMessageBus.d.ts.map +0 -1
  293. package/dist/src/labs/UiShell/createStore.d.ts.map +0 -1
  294. package/dist/src/labs/UiShell/index.d.ts.map +0 -1
  295. package/dist/src/labs/UiShell/renderUiShell.d.ts.map +0 -1
  296. package/dist/src/labs/UiShell/useHasUiShell.d.ts.map +0 -1
  297. package/dist/src/labs/UiShell/useScrollState.d.ts.map +0 -1
  298. package/dist/src/labs/datePickerTheme.d.ts.map +0 -1
  299. package/dist/src/labs/useDateFieldsTranslations.d.ts.map +0 -1
  300. package/dist/src/labs/useOdysseyDateFields.d.ts.map +0 -1
  301. package/dist/src/web-component/renderReactInWebComponent.d.ts.map +0 -1
  302. package/dist/web-component/renderReactInWebComponent.js.map +0 -1
  303. /package/dist/labs/{DatePicker.types.d.js → DatePickers/DatePicker.types.d.js} +0 -0
  304. /package/dist/labs/{useDateFieldsTranslations.js → DatePickers/useDateFieldsTranslations.js} +0 -0
  305. /package/dist/src/labs/{useDateFieldsTranslations.d.ts → DatePickers/useDateFieldsTranslations.d.ts} +0 -0
  306. /package/dist/src/{labs → ui-shell}/UiShell/bufferLatest.d.ts +0 -0
  307. /package/dist/src/{labs → ui-shell}/UiShell/createMessageBus.d.ts +0 -0
  308. /package/dist/src/{labs → ui-shell}/UiShell/createStore.d.ts +0 -0
  309. /package/dist/src/{labs → ui-shell}/UiShell/index.d.ts +0 -0
  310. /package/dist/src/{labs → ui-shell}/UiShell/useScrollState.d.ts +0 -0
  311. /package/dist/{labs → ui-shell}/UiShell/bufferLatest.js +0 -0
  312. /package/dist/{labs → ui-shell}/UiShell/createMessageBus.js +0 -0
  313. /package/dist/{labs → ui-shell}/UiShell/createStore.js +0 -0
  314. /package/dist/{labs → ui-shell}/UiShell/index.js +0 -0
  315. /package/dist/{labs → ui-shell}/UiShell/useScrollState.js +0 -0
  316. /package/src/labs/{DatePicker.types.d.ts → DatePickers/DatePicker.types.d.ts} +0 -0
  317. /package/src/labs/{useDateFieldsTranslations.ts → DatePickers/useDateFieldsTranslations.ts} +0 -0
  318. /package/src/{labs → ui-shell}/UiShell/UiShell.test.tsx +0 -0
  319. /package/src/{labs → ui-shell}/UiShell/bufferLatest.test.ts +0 -0
  320. /package/src/{labs → ui-shell}/UiShell/bufferLatest.ts +0 -0
  321. /package/src/{labs → ui-shell}/UiShell/createMessageBus.test.ts +0 -0
  322. /package/src/{labs → ui-shell}/UiShell/createMessageBus.ts +0 -0
  323. /package/src/{labs → ui-shell}/UiShell/createStore.test.ts +0 -0
  324. /package/src/{labs → ui-shell}/UiShell/createStore.ts +0 -0
  325. /package/src/{labs → ui-shell}/UiShell/index.ts +0 -0
  326. /package/src/{labs → ui-shell}/UiShell/useScrollState.ts +0 -0
@@ -10,151 +10,1076 @@
10
10
  * See the License for the specific language governing permissions and limitations under the License.
11
11
  */
12
12
 
13
- import {
14
- fireEvent,
15
- render,
16
- screen,
17
- waitFor,
18
- within,
19
- } from "@testing-library/react";
20
- import { DataView } from "./index";
21
- import {
22
- data,
23
- columns,
24
- } from "../../../../odyssey-storybook/src/components/odyssey-labs/DataView/personData";
25
- import { filterData } from "../../../../odyssey-storybook/src/components/odyssey-labs/DataView/dataFunctions";
13
+ import { render, screen, waitFor, within } from "@testing-library/react";
14
+ import { userEvent } from "@testing-library/user-event";
15
+ import { DataOnReorderRowsType, DataRow, DataView } from "./index";
16
+ import { data, columns, filterData, reorderData } from "./testSupportData";
17
+ import { EmptyState } from "../../EmptyState";
18
+ import { DataTableRowData } from "../../DataTable";
19
+ import { Button } from "../../Buttons";
20
+ import { MenuItem } from "../../Buttons";
21
+ import { MRT_RowSelectionState } from "material-react-table";
22
+ import { getControlledElement } from "../../test-selectors/linkedHtmlSelectors";
26
23
 
27
24
  const getData = ({ ...props }) => {
28
25
  return filterData({ data, ...props });
29
26
  };
30
27
 
28
+ const listItemProps = (row: DataRow) => ({
29
+ title: row.name,
30
+ overline: "List card",
31
+ });
32
+
33
+ const gridItemProps = (row: DataRow) => ({
34
+ title: row.name,
35
+ overline: "Grid card",
36
+ });
37
+
38
+ const waitUntilTableLoadedHack = async () => {
39
+ return expect(await screen.findByText(data[0].name)).toBeVisible();
40
+ };
41
+
31
42
  describe("DataView", () => {
32
- it("displays the expected number of rows by default", async () => {
43
+ describe("DataView layouts", () => {
44
+ test("displays a table view", async () => {
45
+ const { container } = render(
46
+ <DataView
47
+ availableLayouts={["table"]}
48
+ getData={getData}
49
+ tableLayoutOptions={{
50
+ columns,
51
+ }}
52
+ />,
53
+ );
54
+
55
+ await waitUntilTableLoadedHack();
56
+
57
+ expect(within(container).queryByRole("table")).not.toBeNull();
58
+ expect(within(container).queryByRole("list")).toBeNull();
59
+ });
60
+
61
+ test("displays a list view", async () => {
62
+ const { container } = render(
63
+ <DataView
64
+ availableLayouts={["list"]}
65
+ getData={getData}
66
+ cardLayoutOptions={{
67
+ itemProps: listItemProps,
68
+ }}
69
+ />,
70
+ );
71
+
72
+ await waitUntilTableLoadedHack();
73
+
74
+ expect(within(container).queryByRole("table")).toBeNull();
75
+ expect(within(container).queryByRole("list")).not.toBeNull();
76
+ });
77
+
78
+ test("displays a grid view", async () => {
79
+ const { container } = render(
80
+ <DataView
81
+ availableLayouts={["grid"]}
82
+ getData={getData}
83
+ cardLayoutOptions={{
84
+ itemProps: gridItemProps,
85
+ }}
86
+ />,
87
+ );
88
+
89
+ await waitUntilTableLoadedHack();
90
+
91
+ expect(within(container).queryByRole("table")).toBeNull();
92
+ expect(within(container).queryByRole("list")).not.toBeNull();
93
+ });
94
+
95
+ test("displays the layout switcher", async () => {
96
+ const user = userEvent.setup();
97
+
98
+ render(
99
+ <DataView
100
+ availableLayouts={["table", "list"]}
101
+ getData={getData}
102
+ tableLayoutOptions={{
103
+ columns,
104
+ }}
105
+ cardLayoutOptions={{
106
+ itemProps: listItemProps,
107
+ }}
108
+ />,
109
+ );
110
+
111
+ const layoutSwitcherButton = screen.getByLabelText("Layout", {
112
+ selector: "button",
113
+ });
114
+ await user.click(layoutSwitcherButton);
115
+
116
+ const layoutSwitcherMenu = getControlledElement({
117
+ element: layoutSwitcherButton,
118
+ });
119
+ expect(within(layoutSwitcherMenu).getAllByRole("menuitem")).toHaveLength(
120
+ 2,
121
+ );
122
+
123
+ expect(
124
+ within(layoutSwitcherMenu).getByRole("menuitem", { name: "Table" }),
125
+ ).toBeVisible();
126
+ expect(
127
+ within(layoutSwitcherMenu).getByRole("menuitem", { name: "List" }),
128
+ ).toBeVisible();
129
+ });
130
+ });
131
+
132
+ test("can display meta text", async () => {
133
+ const metaText = "Last updated 12 hours ago";
134
+
33
135
  render(
34
136
  <DataView
35
137
  availableLayouts={["table"]}
36
138
  getData={getData}
37
139
  tableLayoutOptions={{
38
- columns: columns,
140
+ columns,
39
141
  }}
40
- hasSearch
41
- hasPagination
42
- // virtualization has to be false for the tests to work properly
43
- enableVirtualization={false}
44
- paginationType="loadMore"
45
- resultsPerPage={20}
142
+ metaText={metaText}
46
143
  />,
47
144
  );
48
145
 
49
- const tableElement = await screen.findByRole("table", { name: "" });
50
- const rowElements = within(tableElement).getAllByRole("row", {
51
- hidden: false,
146
+ expect(screen.getByText(metaText)).toBeVisible();
147
+ });
148
+
149
+ describe("Filter and search", () => {
150
+ test("can filter rows", async () => {
151
+ const user = userEvent.setup();
152
+
153
+ render(
154
+ <DataView
155
+ availableLayouts={["table"]}
156
+ hasFilters
157
+ getData={getData}
158
+ tableLayoutOptions={{
159
+ columns,
160
+ }}
161
+ />,
162
+ );
163
+
164
+ expect(await screen.findByText(data[0].name)).toBeVisible();
165
+ expect(await screen.findByText(data[1].name)).toBeVisible();
166
+
167
+ const filterButton = screen.getByLabelText("Filters", {
168
+ selector: "button",
169
+ });
170
+ await user.click(filterButton);
171
+
172
+ const filterMenu = getControlledElement({ element: filterButton });
173
+ const nameMenuItem = within(filterMenu).getByRole("menuitem", {
174
+ name: /Name/i,
175
+ });
176
+ await user.click(nameMenuItem);
177
+
178
+ const nameFilterMenu = getControlledElement({ element: nameMenuItem });
179
+ const nameInput = within(nameFilterMenu).getByLabelText("Name");
180
+ const submitButton = within(nameFilterMenu).getByRole("button");
181
+
182
+ await user.click(nameInput);
183
+ await user.keyboard(`${data[1].name}{ENTER}`);
184
+ await user.click(submitButton);
185
+
186
+ await screen.findByText("Clear filters");
187
+
188
+ const table = screen.getByRole("table");
189
+ expect(screen.queryByText(data[0].name)).toBeNull();
190
+ expect(await within(table).findByText(data[1].name)).toBeVisible();
191
+ });
192
+
193
+ test("can search rows", async () => {
194
+ const user = userEvent.setup();
195
+
196
+ render(
197
+ <DataView
198
+ availableLayouts={["table"]}
199
+ hasSearch
200
+ hasSearchSubmitButton
201
+ getData={getData}
202
+ tableLayoutOptions={{
203
+ columns,
204
+ }}
205
+ />,
206
+ );
207
+
208
+ expect(await screen.findByText(data[0].name)).toBeVisible();
209
+ expect(await screen.findByText(data[1].name)).toBeVisible();
210
+
211
+ const searchInput = screen.getByPlaceholderText(/Search/i);
212
+ const submitButton = screen.getByText("Search", { selector: "button" });
213
+ await user.click(searchInput);
214
+ await user.keyboard(`${data[1].name}`);
215
+ await user.click(submitButton);
216
+
217
+ const table = screen.getByRole("table");
218
+ expect(screen.queryByText(data[0].name)).toBeNull();
219
+ expect(await within(table).findByText(data[1].name)).toBeVisible();
220
+ });
221
+
222
+ test("can clear the search input", async () => {
223
+ const user = userEvent.setup();
224
+
225
+ render(
226
+ <DataView
227
+ availableLayouts={["table"]}
228
+ hasSearch
229
+ hasSearchSubmitButton
230
+ getData={getData}
231
+ tableLayoutOptions={{
232
+ columns,
233
+ }}
234
+ />,
235
+ );
236
+
237
+ expect(await screen.findByText(data[0].name)).toBeVisible();
238
+ expect(await screen.findByText(data[1].name)).toBeVisible();
239
+
240
+ const searchInput = screen.getByPlaceholderText(/Search/i);
241
+ const submitButton = screen.getByText("Search", { selector: "button" });
242
+ await user.click(searchInput);
243
+ await user.keyboard(`${data[1].name}`);
244
+ await user.click(submitButton);
245
+
246
+ const table = screen.getByRole("table");
247
+ expect(screen.queryByText(data[0].name)).toBeNull();
248
+ expect(await within(table).findByText(data[1].name)).toBeVisible();
249
+
250
+ const clearButton = screen.getByLabelText("Clear", {
251
+ selector: "button",
252
+ });
253
+ await user.click(clearButton);
254
+
255
+ waitFor(() => {
256
+ expect(searchInput).toHaveValue("");
257
+ expect(screen.getAllByRole("row")).toHaveLength(7);
258
+ expect(screen.getByText(data[0].name)).toBeVisible();
259
+ expect(screen.getByText(data[1].name)).toBeVisible();
260
+ });
52
261
  });
53
- expect(rowElements.length).toBe(21);
54
262
  });
55
263
 
56
- // TODO: Figure out why this test broke when switching to happy-dom.
57
- it.skip("displays the expected number of rows on load more", async () => {
264
+ describe("Row actions", () => {
265
+ test("can display row action menu", async () => {
266
+ const user = userEvent.setup();
267
+
268
+ const rowActionMenuItems = (row: DataTableRowData) => (
269
+ <MenuItem>Action for {row.original.name}</MenuItem>
270
+ );
271
+
272
+ render(
273
+ <DataView
274
+ availableLayouts={["table"]}
275
+ getData={getData}
276
+ tableLayoutOptions={{
277
+ columns,
278
+ rowActionMenuItems: rowActionMenuItems,
279
+ }}
280
+ />,
281
+ );
282
+
283
+ await waitUntilTableLoadedHack();
284
+
285
+ // Index 1 because row[0] is the th row
286
+ const firstBodyRow = (await screen.findAllByRole("row"))[1];
287
+ const firstBodyRowActionButton = within(firstBodyRow).getByRole("button");
288
+ await user.click(firstBodyRowActionButton);
289
+
290
+ const actionMenu = getControlledElement({
291
+ element: firstBodyRowActionButton,
292
+ });
293
+ const actionMenuItem = within(actionMenu).getByRole("menuitem");
294
+ expect(
295
+ within(actionMenuItem).getByText(`Action for ${data[0].name}`),
296
+ ).toBeVisible();
297
+ });
298
+
299
+ test("can display row action buttons", async () => {
300
+ const rowActionButtons = (row: DataTableRowData) => (
301
+ <Button variant="primary" label={`Button for ${row?.original?.name}`} />
302
+ );
303
+
304
+ render(
305
+ <DataView
306
+ availableLayouts={["table"]}
307
+ getData={getData}
308
+ tableLayoutOptions={{
309
+ columns,
310
+ rowActionButtons: rowActionButtons,
311
+ }}
312
+ />,
313
+ );
314
+
315
+ await waitUntilTableLoadedHack();
316
+
317
+ // Index 1 because row[0] is the th row
318
+ const firstBodyRow = (await screen.findAllByRole("row"))[1];
319
+ const firstBodyRowActionButton = within(firstBodyRow).getByText(
320
+ `Button for ${data[0].name}`,
321
+ { selector: "button" },
322
+ );
323
+
324
+ expect(firstBodyRowActionButton).toBeVisible();
325
+ });
326
+ });
327
+
328
+ describe("Row selection", () => {
329
+ test("can select table rows", async () => {
330
+ const user = userEvent.setup();
331
+
332
+ render(
333
+ <DataView
334
+ availableLayouts={["table"]}
335
+ getData={getData}
336
+ hasRowSelection
337
+ tableLayoutOptions={{
338
+ columns,
339
+ }}
340
+ />,
341
+ );
342
+
343
+ await waitUntilTableLoadedHack();
344
+
345
+ const checkboxes = screen.getAllByRole("checkbox");
346
+ await user.click(checkboxes[1]);
347
+
348
+ const selectedText = screen.getByText("1 selected", {
349
+ selector: "button",
350
+ });
351
+ expect(selectedText).toBeVisible();
352
+ });
353
+
354
+ test("can select all rows", async () => {
355
+ const user = userEvent.setup();
356
+
357
+ render(
358
+ <DataView
359
+ availableLayouts={["table"]}
360
+ getData={getData}
361
+ hasRowSelection
362
+ tableLayoutOptions={{
363
+ columns,
364
+ }}
365
+ />,
366
+ );
367
+
368
+ await waitUntilTableLoadedHack();
369
+
370
+ const checkboxes = screen.getAllByRole("checkbox");
371
+ await user.click(checkboxes[0]);
372
+
373
+ const selectedText = screen.getByText(`${data.length} selected`, {
374
+ selector: "button",
375
+ });
376
+ expect(selectedText).toBeVisible();
377
+ });
378
+
379
+ test("can select card rows", async () => {
380
+ const user = userEvent.setup();
381
+
382
+ render(
383
+ <DataView
384
+ availableLayouts={["grid"]}
385
+ getData={getData}
386
+ hasRowSelection
387
+ cardLayoutOptions={{
388
+ itemProps: gridItemProps,
389
+ }}
390
+ />,
391
+ );
392
+
393
+ await waitUntilTableLoadedHack();
394
+
395
+ const checkboxes = screen.getAllByRole("checkbox");
396
+ await user.click(checkboxes[1]);
397
+
398
+ const selectedText = screen.getByText("1 selected", {
399
+ selector: "button",
400
+ });
401
+ expect(selectedText).toBeVisible();
402
+ });
403
+
404
+ test("can select all card rows", async () => {
405
+ const user = userEvent.setup();
406
+
407
+ render(
408
+ <DataView
409
+ availableLayouts={["table"]}
410
+ getData={getData}
411
+ hasRowSelection
412
+ tableLayoutOptions={{
413
+ columns,
414
+ }}
415
+ />,
416
+ );
417
+
418
+ await waitUntilTableLoadedHack();
419
+
420
+ const checkboxes = screen.getAllByRole("checkbox");
421
+ await user.click(checkboxes[0]);
422
+
423
+ const selectedText = screen.getByText(`${data.length} selected`, {
424
+ selector: "button",
425
+ });
426
+ expect(selectedText).toBeVisible();
427
+ });
428
+
429
+ test("can deselect rows", async () => {
430
+ const user = userEvent.setup();
431
+
432
+ render(
433
+ <DataView
434
+ availableLayouts={["table"]}
435
+ getData={getData}
436
+ hasRowSelection
437
+ tableLayoutOptions={{
438
+ columns,
439
+ }}
440
+ />,
441
+ );
442
+
443
+ await waitUntilTableLoadedHack();
444
+
445
+ const checkboxes = screen.getAllByRole("checkbox");
446
+ await user.click(checkboxes[1]);
447
+ await user.click(checkboxes[2]);
448
+
449
+ expect(
450
+ screen.getByText("2 selected", { selector: "button" }),
451
+ ).toBeVisible();
452
+
453
+ await user.click(checkboxes[1]);
454
+
455
+ expect(
456
+ screen.getByText("1 selected", { selector: "button" }),
457
+ ).toBeVisible();
458
+ });
459
+
460
+ test("can deselect all rows", async () => {
461
+ const user = userEvent.setup();
462
+
463
+ render(
464
+ <DataView
465
+ availableLayouts={["table"]}
466
+ getData={getData}
467
+ hasRowSelection
468
+ tableLayoutOptions={{
469
+ columns,
470
+ }}
471
+ />,
472
+ );
473
+
474
+ await waitUntilTableLoadedHack();
475
+
476
+ const checkboxes = screen.getAllByRole("checkbox");
477
+ await user.click(checkboxes[0]);
478
+
479
+ const selectedText = screen.getByText(`${data.length} selected`, {
480
+ selector: "button",
481
+ });
482
+ expect(selectedText).toBeVisible();
483
+
484
+ await user.click(checkboxes[0]);
485
+
486
+ expect(
487
+ screen.queryByText(`${data.length} selected`, { selector: "button" }),
488
+ ).toBeNull();
489
+ });
490
+
491
+ test("can perform bulk actions on rows", async () => {
492
+ const user = userEvent.setup();
493
+
494
+ const bulkActionMenuItems = (selectedRows: MRT_RowSelectionState) => (
495
+ <MenuItem>Bulk action for {Object.keys(selectedRows).length}</MenuItem>
496
+ );
497
+
498
+ render(
499
+ <DataView
500
+ availableLayouts={["table"]}
501
+ getData={getData}
502
+ hasRowSelection
503
+ tableLayoutOptions={{
504
+ columns,
505
+ }}
506
+ bulkActionMenuItems={bulkActionMenuItems}
507
+ />,
508
+ );
509
+
510
+ await waitUntilTableLoadedHack();
511
+
512
+ const selectAllButton = screen.getByText("Select all", {
513
+ selector: "button",
514
+ });
515
+ await user.click(selectAllButton);
516
+
517
+ const selectedButton = screen.getByText(`${data.length} selected`, {
518
+ selector: "button",
519
+ });
520
+ await user.click(selectedButton);
521
+
522
+ const bulkActionsMenu = getControlledElement({ element: selectedButton });
523
+ const bulkActionsMenuItem = within(bulkActionsMenu).getByRole("menuitem");
524
+ expect(bulkActionsMenuItem.textContent).toBe(
525
+ `Bulk action for ${data.length}`,
526
+ );
527
+ });
528
+ });
529
+
530
+ describe("Row reordering", () => {
531
+ test("can reorder rows", async () => {
532
+ const user = userEvent.setup();
533
+
534
+ let updatedData = data.slice();
535
+
536
+ const handleReorderRows = ({
537
+ rowId,
538
+ newRowIndex,
539
+ }: DataOnReorderRowsType) => {
540
+ updatedData = reorderData({ data: updatedData, rowId, newRowIndex });
541
+ };
542
+
543
+ render(
544
+ <DataView
545
+ availableLayouts={["table"]}
546
+ getData={() => updatedData}
547
+ hasRowReordering
548
+ onReorderRows={handleReorderRows}
549
+ tableLayoutOptions={{
550
+ columns,
551
+ }}
552
+ />,
553
+ );
554
+
555
+ expect(await screen.findByText(data[0].name)).toBeVisible();
556
+ expect(await screen.findByText(data[1].name)).toBeVisible();
557
+
558
+ const moreActionsButton = within(
559
+ screen.getAllByRole("row")[2],
560
+ ).getByLabelText("More actions", { selector: "button" });
561
+ await user.click(moreActionsButton);
562
+
563
+ const moreActionsMenu = getControlledElement({
564
+ element: moreActionsButton,
565
+ });
566
+ const moveForwardButton = within(moreActionsMenu).getByRole("menuitem", {
567
+ name: "Bring forward",
568
+ });
569
+ await user.click(moveForwardButton);
570
+
571
+ const updatedRows = await screen.findAllByRole("row");
572
+
573
+ // Confirm that the first two rows have swapped
574
+ expect(updatedRows[1].textContent).toContain(data[1].name);
575
+ expect(updatedRows[2].textContent).toContain(data[0].name);
576
+ });
577
+
578
+ test("can reorder to front", async () => {
579
+ const user = userEvent.setup();
580
+
581
+ let updatedData = data.slice();
582
+
583
+ const handleReorderRows = ({
584
+ rowId,
585
+ newRowIndex,
586
+ }: DataOnReorderRowsType) => {
587
+ updatedData = reorderData({ data: updatedData, rowId, newRowIndex });
588
+ };
589
+
590
+ render(
591
+ <DataView
592
+ availableLayouts={["table"]}
593
+ getData={() => updatedData}
594
+ hasRowReordering
595
+ onReorderRows={handleReorderRows}
596
+ tableLayoutOptions={{
597
+ columns,
598
+ }}
599
+ />,
600
+ );
601
+
602
+ expect(await screen.findByText(data[0].name)).toBeVisible();
603
+ expect(await screen.findByText(data[5].name)).toBeVisible();
604
+
605
+ const moreActionsButton = within(
606
+ screen.getAllByRole("row")[6],
607
+ ).getByLabelText("More actions", { selector: "button" });
608
+ await user.click(moreActionsButton);
609
+
610
+ const moreActionsMenu = getControlledElement({
611
+ element: moreActionsButton,
612
+ });
613
+ const moveToFrontButton = within(moreActionsMenu).getByRole("menuitem", {
614
+ name: "Bring to front",
615
+ });
616
+ await user.click(moveToFrontButton);
617
+
618
+ const updatedRows = await screen.findAllByRole("row");
619
+
620
+ // Confirm that the first two rows have swapped
621
+ expect(updatedRows[1].textContent).toContain(data[5].name);
622
+ expect(updatedRows[2].textContent).toContain(data[0].name);
623
+ });
624
+
625
+ test("can reorder to back", async () => {
626
+ const user = userEvent.setup();
627
+
628
+ let updatedData = data.slice();
629
+
630
+ const handleReorderRows = ({
631
+ rowId,
632
+ newRowIndex,
633
+ }: DataOnReorderRowsType) => {
634
+ updatedData = reorderData({ data: updatedData, rowId, newRowIndex });
635
+ };
636
+
637
+ render(
638
+ <DataView
639
+ availableLayouts={["table"]}
640
+ getData={() => updatedData}
641
+ hasRowReordering
642
+ onReorderRows={handleReorderRows}
643
+ totalRows={updatedData.length}
644
+ tableLayoutOptions={{
645
+ columns,
646
+ }}
647
+ />,
648
+ );
649
+
650
+ expect(await screen.findByText(data[0].name)).toBeVisible();
651
+ expect(await screen.findByText(data[5].name)).toBeVisible();
652
+
653
+ const moreActionsButton = within(
654
+ screen.getAllByRole("row")[1],
655
+ ).getByLabelText("More actions", { selector: "button" });
656
+ await user.click(moreActionsButton);
657
+
658
+ const moreActionsMenu = getControlledElement({
659
+ element: moreActionsButton,
660
+ });
661
+ const moveToBackButton = within(moreActionsMenu).getByRole("menuitem", {
662
+ name: "Send to back",
663
+ });
664
+ await user.click(moveToBackButton);
665
+
666
+ const updatedRows = await screen.findAllByRole("row");
667
+
668
+ expect(updatedRows[6].textContent).toContain(data[0].name);
669
+ expect(updatedRows[5].textContent).toContain(data[5].name);
670
+ });
671
+
672
+ test("can expand table rows", async () => {
673
+ const user = userEvent.setup();
674
+
675
+ const tableDetails = ({ row }: { row: DataTableRowData }) => {
676
+ return <p>This is additional content for {row.original.name}</p>;
677
+ };
678
+
679
+ render(
680
+ <DataView
681
+ availableLayouts={["table"]}
682
+ getData={getData}
683
+ tableLayoutOptions={{
684
+ columns,
685
+ renderDetailPanel: tableDetails,
686
+ }}
687
+ />,
688
+ );
689
+
690
+ await waitUntilTableLoadedHack();
691
+ expect(
692
+ screen.queryByText(`This is additional content for ${data[0].name}`),
693
+ ).toBeNull();
694
+
695
+ const firstBodyRow = (await screen.findAllByRole("row"))[1];
696
+ const firstBodyRowExpandButton = within(firstBodyRow).getByLabelText(
697
+ "Expand",
698
+ { selector: "button" },
699
+ );
700
+ await user.click(firstBodyRowExpandButton);
701
+
702
+ expect(
703
+ screen.queryByText(`This is additional content for ${data[0].name}`),
704
+ ).not.toBeNull();
705
+ });
706
+ });
707
+
708
+ test("can expand card rows", async () => {
709
+ const user = userEvent.setup();
710
+
711
+ const cardDetails = ({ row }: { row: DataTableRowData }) => {
712
+ return <p>This is additional content for {row.name}</p>;
713
+ };
714
+
715
+ render(
716
+ <DataView
717
+ availableLayouts={["grid"]}
718
+ getData={getData}
719
+ cardLayoutOptions={{
720
+ itemProps: gridItemProps,
721
+ renderDetailPanel: cardDetails,
722
+ }}
723
+ />,
724
+ );
725
+
726
+ expect(await screen.findAllByText(data[0].name)).toHaveLength(1);
727
+ expect(
728
+ screen.queryByText(`This is additional content for ${data[0].name}`),
729
+ ).toBeNull();
730
+
731
+ const firstCard = (await screen.findAllByRole("listitem"))[0];
732
+ const firstCardExpandButton = within(firstCard).getByLabelText("Expand", {
733
+ selector: "button",
734
+ });
735
+ await user.click(firstCardExpandButton);
736
+
737
+ expect(
738
+ screen.queryByText(`This is additional content for ${data[0].name}`),
739
+ ).not.toBeNull();
740
+ });
741
+
742
+ test("can display empty state", async () => {
743
+ const emptyText = "This is the empty state text.";
744
+
745
+ render(
746
+ <DataView
747
+ availableLayouts={["table"]}
748
+ getData={() => []}
749
+ tableLayoutOptions={{
750
+ columns,
751
+ }}
752
+ emptyPlaceholder={
753
+ <EmptyState heading="Empty" description={emptyText} />
754
+ }
755
+ />,
756
+ );
757
+
758
+ expect(await screen.findByText(emptyText)).not.toBeNull();
759
+ });
760
+
761
+ test("can display no-results state", async () => {
762
+ const noResultsText = "This is the no results state text.";
763
+
764
+ render(
765
+ <DataView
766
+ availableLayouts={["table"]}
767
+ getData={() => []}
768
+ tableLayoutOptions={{
769
+ columns,
770
+ }}
771
+ noResultsPlaceholder={
772
+ <EmptyState heading="No results" description={noResultsText} />
773
+ }
774
+ />,
775
+ );
776
+
777
+ expect(await screen.findByText(noResultsText)).not.toBeNull();
778
+ });
779
+
780
+ test("can sort rows", async () => {
781
+ const user = userEvent.setup();
782
+
58
783
  render(
59
784
  <DataView
60
785
  availableLayouts={["table"]}
61
786
  getData={getData}
62
787
  tableLayoutOptions={{
63
- columns: columns,
788
+ columns,
789
+ hasSorting: true,
64
790
  }}
65
- hasSearch
66
- hasPagination
67
- // virtualization has to be false for the tests to work properly
68
- enableVirtualization={false}
69
- paginationType="loadMore"
70
- resultsPerPage={20}
71
791
  />,
72
792
  );
73
793
 
74
- const tableElement = await screen.findByRole("table", { name: "" });
75
- const rowElements = within(tableElement).getAllByRole("row", {
76
- hidden: false,
794
+ await waitUntilTableLoadedHack();
795
+
796
+ const initialRows = screen.getAllByRole("row");
797
+ expect(initialRows[1].textContent).toContain(data[0].name);
798
+
799
+ const idHeader = screen.getByRole("button", {
800
+ name: "Sort by ID descending",
77
801
  });
78
- expect(rowElements.length).toBe(21);
802
+ await user.click(idHeader);
79
803
 
80
- waitFor(() => {
81
- fireEvent.click(screen.getByText("Show more"));
804
+ expect(await screen.findByText(data[0].name)).toBeVisible();
82
805
 
83
- const loadedRows = within(tableElement).getAllByRole("row", {
84
- hidden: false,
85
- });
86
- expect(loadedRows.length).toBe(41);
806
+ const sortedRows = screen.getAllByRole("row");
807
+ expect(sortedRows[6].textContent).toContain(data[0].name);
808
+ });
809
+
810
+ test("can change row density", async () => {
811
+ const user = userEvent.setup();
812
+
813
+ render(
814
+ <DataView
815
+ availableLayouts={["table"]}
816
+ getData={getData}
817
+ tableLayoutOptions={{
818
+ columns,
819
+ hasChangeableDensity: true,
820
+ }}
821
+ />,
822
+ );
823
+
824
+ await waitUntilTableLoadedHack();
825
+
826
+ // Since table density is a purely visible attribute, there's no ARIA
827
+ // attribute to target here. We're forced to use the className directly.
828
+ const tBody = screen.getAllByRole("row")[1].parentElement;
829
+ expect(tBody?.className).not.toContain("MuiTableBody-compact");
830
+
831
+ const densityButton = screen.getByLabelText("Table density", {
832
+ selector: "button",
833
+ });
834
+ await user.click(densityButton);
835
+
836
+ const densityMenu = getControlledElement({ element: densityButton });
837
+ const densityCompact = within(densityMenu).getByRole("menuitem", {
838
+ name: "Compact",
87
839
  });
840
+ await user.click(densityCompact);
841
+
842
+ expect(tBody?.className).toContain("MuiTableBody-compact");
88
843
  });
89
844
 
90
- // TODO: Figure out why this test broke when switching to happy-dom.
91
- it.skip("resets the rows when searching", async () => {
845
+ test("can change column visibility", async () => {
846
+ const user = userEvent.setup();
847
+
92
848
  render(
93
849
  <DataView
94
850
  availableLayouts={["table"]}
95
851
  getData={getData}
96
852
  tableLayoutOptions={{
97
- columns: columns,
853
+ columns,
854
+ hasColumnVisibility: true,
98
855
  }}
99
- hasSearch
100
- hasPagination
101
- // virtualization has to be false for the tests to work properly
102
- enableVirtualization={false}
103
- paginationType="loadMore"
104
- resultsPerPage={20}
105
856
  />,
106
857
  );
107
858
 
108
- const tableElement = await screen.findByRole("table", { name: "" });
109
- const rowElements = within(tableElement).getAllByRole("row", {
110
- hidden: false,
859
+ // Detect if the data has loaded in
860
+ await screen.findByText(data[0].city);
861
+
862
+ const visibilityButton = screen.getByLabelText("Show/hide columns", {
863
+ selector: "button",
111
864
  });
112
- expect(rowElements.length).toBe(21);
865
+ await user.click(visibilityButton);
866
+
867
+ const visibilityMenu = getControlledElement({ element: visibilityButton });
868
+
869
+ const cityCheckbox = within(visibilityMenu).getByText("City");
870
+ await user.click(cityCheckbox);
113
871
 
114
- fireEvent.click(screen.getByText("Show more"));
872
+ expect(screen.queryByText(data[0].city)).toBeNull();
873
+ });
115
874
 
116
- waitFor(() => {
117
- const loadedRows = within(tableElement).getAllByRole("row", {
118
- hidden: false,
875
+ test("can resize columns", async () => {
876
+ render(
877
+ <DataView
878
+ availableLayouts={["table"]}
879
+ getData={getData}
880
+ tableLayoutOptions={{
881
+ columns,
882
+ hasColumnResizing: true,
883
+ }}
884
+ />,
885
+ );
886
+
887
+ await waitUntilTableLoadedHack();
888
+
889
+ const rows = await screen.findAllByRole("row");
890
+ const tHead = rows[0].parentElement;
891
+
892
+ // Ensure that the resize handle is displayed when
893
+ // hasColumnResizing is true
894
+ const hrElement = tHead!.querySelector("hr");
895
+ expect(tHead).toContainElement(hrElement);
896
+ });
897
+
898
+ describe("Pagination", () => {
899
+ test("displays paged pagination", async () => {
900
+ render(
901
+ <DataView
902
+ availableLayouts={["table"]}
903
+ getData={getData}
904
+ hasPagination
905
+ paginationType="paged"
906
+ tableLayoutOptions={{
907
+ columns,
908
+ }}
909
+ />,
910
+ );
911
+
912
+ await waitUntilTableLoadedHack();
913
+
914
+ const paginationContainer = await screen.findByLabelText("Pagination", {
915
+ selector: "nav",
119
916
  });
120
- expect(loadedRows.length).toBe(41);
917
+ expect(
918
+ within(paginationContainer).getByLabelText("Next page", {
919
+ selector: "button",
920
+ }),
921
+ ).toBeInTheDocument();
121
922
  });
122
923
 
123
- const searchField = screen.getByPlaceholderText("Search");
124
- fireEvent.change(searchField, { target: { value: "John" } });
924
+ test("displays loadMore pagination", async () => {
925
+ render(
926
+ <DataView
927
+ availableLayouts={["table"]}
928
+ getData={getData}
929
+ hasPagination
930
+ paginationType="loadMore"
931
+ enableVirtualization={false}
932
+ tableLayoutOptions={{
933
+ columns,
934
+ }}
935
+ />,
936
+ );
937
+
938
+ await waitUntilTableLoadedHack();
939
+
940
+ expect(
941
+ screen.getByText("Show more", { selector: "button" }),
942
+ ).toBeInTheDocument();
943
+ });
944
+
945
+ test("can load more rows via loadMore pagination", async () => {
946
+ const user = userEvent.setup();
125
947
 
126
- waitFor(() => {
127
- const rowsAfterFilter = within(tableElement).getAllByRole("row", {
128
- hidden: false,
948
+ render(
949
+ <DataView
950
+ availableLayouts={["table"]}
951
+ getData={getData}
952
+ hasPagination
953
+ paginationType="loadMore"
954
+ resultsPerPage={3}
955
+ enableVirtualization={false}
956
+ tableLayoutOptions={{
957
+ columns,
958
+ }}
959
+ />,
960
+ );
961
+
962
+ await waitUntilTableLoadedHack();
963
+
964
+ expect(screen.getAllByRole("row")).toHaveLength(4);
965
+
966
+ const loadMoreButton = screen.getByText("Show more", {
967
+ selector: "button",
968
+ });
969
+ await user.click(loadMoreButton);
970
+
971
+ await waitFor(() => {
972
+ expect(screen.getAllByRole("row")).toHaveLength(7); // 6 data rows + header row
129
973
  });
130
- expect(rowsAfterFilter.length).toBeLessThanOrEqual(21);
131
974
  });
132
- });
133
975
 
134
- it("fires onPaginationChange when pagination changes", async () => {
135
- let currentPage = 1;
136
- const onPaginationChange = (pagination: {
137
- pageIndex: number;
138
- pageSize: number;
139
- }) => {
140
- currentPage = pagination.pageIndex;
141
- };
976
+ test("can go to the next page", async () => {
977
+ const user = userEvent.setup();
142
978
 
143
- render(
144
- <>
979
+ render(
145
980
  <DataView
981
+ availableLayouts={["table"]}
146
982
  getData={getData}
147
983
  hasPagination
148
- onPaginationChange={onPaginationChange}
149
- />
150
- </>,
151
- );
984
+ paginationType="paged"
985
+ resultsPerPage={2}
986
+ tableLayoutOptions={{
987
+ columns,
988
+ }}
989
+ />,
990
+ );
991
+
992
+ await waitUntilTableLoadedHack();
993
+
994
+ expect(screen.queryByText(data[0].name)).not.toBeNull();
995
+ expect(screen.queryByText(data[2].name)).toBeNull();
996
+
997
+ const nextPageButton = screen.getByLabelText("Next page", {
998
+ selector: "button",
999
+ });
1000
+ await user.click(nextPageButton);
1001
+
1002
+ await screen.findByText(data[2].name);
1003
+
1004
+ expect(screen.queryByText(data[0].name)).toBeNull();
1005
+ expect(screen.queryByText(data[2].name)).not.toBeNull();
1006
+ });
1007
+
1008
+ test("can go to the previous page", async () => {
1009
+ const user = userEvent.setup();
1010
+
1011
+ render(
1012
+ <DataView
1013
+ availableLayouts={["table"]}
1014
+ getData={getData}
1015
+ hasPagination
1016
+ paginationType="paged"
1017
+ resultsPerPage={2}
1018
+ tableLayoutOptions={{
1019
+ columns,
1020
+ }}
1021
+ />,
1022
+ );
1023
+
1024
+ await waitUntilTableLoadedHack();
1025
+
1026
+ expect(screen.queryByText(data[0].name)).not.toBeNull();
1027
+ expect(screen.queryByText(data[2].name)).toBeNull();
1028
+
1029
+ const nextPageButton = screen.getByLabelText("Next page", {
1030
+ selector: "button",
1031
+ });
1032
+ await user.click(nextPageButton);
1033
+
1034
+ await screen.findByText(data[2].name);
1035
+
1036
+ expect(screen.queryByText(data[0].name)).toBeNull();
1037
+ expect(screen.queryByText(data[2].name)).not.toBeNull();
1038
+
1039
+ const prevPageButton = screen.getByLabelText("Previous page", {
1040
+ selector: "button",
1041
+ });
1042
+ await user.click(prevPageButton);
1043
+
1044
+ await waitUntilTableLoadedHack();
1045
+
1046
+ expect(screen.queryByText(data[0].name)).not.toBeNull();
1047
+ expect(screen.queryByText(data[2].name)).toBeNull();
1048
+ });
1049
+
1050
+ test("can disable the next page button based on max rows", async () => {
1051
+ const user = userEvent.setup();
1052
+
1053
+ render(
1054
+ <DataView
1055
+ availableLayouts={["table"]}
1056
+ getData={getData}
1057
+ hasPagination
1058
+ paginationType="paged"
1059
+ resultsPerPage={data.length - 1}
1060
+ totalRows={data.length}
1061
+ tableLayoutOptions={{
1062
+ columns,
1063
+ }}
1064
+ />,
1065
+ );
1066
+
1067
+ await waitUntilTableLoadedHack();
1068
+
1069
+ const nextPageButton = screen.getByLabelText("Next page", {
1070
+ selector: "button",
1071
+ });
1072
+ const prevPageButton = screen.getByLabelText("Previous page", {
1073
+ selector: "button",
1074
+ });
1075
+
1076
+ expect(prevPageButton).toBeDisabled();
1077
+ expect(nextPageButton).not.toBeDisabled();
152
1078
 
153
- const nextButton = screen.getByLabelText("Next page");
154
- fireEvent.click(nextButton);
1079
+ await user.click(nextPageButton);
155
1080
 
156
- await waitFor(() => {
157
- expect(currentPage).toBe(2);
1081
+ expect(prevPageButton).not.toBeDisabled();
1082
+ expect(nextPageButton).toBeDisabled();
158
1083
  });
159
1084
  });
160
1085
  });