diff --git a/packages/react/src/components/DataTable/DataTable.js b/packages/react/src/components/DataTable/DataTable.js
index 5b119aad5aca..532a95eac896 100644
--- a/packages/react/src/components/DataTable/DataTable.js
+++ b/packages/react/src/components/DataTable/DataTable.js
@@ -233,9 +233,10 @@ export default class DataTable extends React.Component {
*
* @param {object} config
* @param {Function} config.onClick a custom click handler for the expand header
+ * @param {Function} config.onExpand a custom click handler called when header is expanded
* @returns {object}
*/
- getExpandHeaderProps = ({ onClick, ...rest } = {}) => {
+ getExpandHeaderProps = ({ onClick, onExpand, ...rest } = {}) => {
const { translateWithId: t } = this.props;
const { isExpandedAll, rowIds, rowsById } = this.state;
const isExpanded =
@@ -251,6 +252,7 @@ export default class DataTable extends React.Component {
// handler
onExpand: composeEventHandlers([
this.handleOnExpandAll,
+ onExpand,
onClick
? this.handleOnExpandHeaderClick(onClick, {
isExpanded,
diff --git a/packages/react/src/components/DataTable/__tests__/TableExpandHeader-test.js b/packages/react/src/components/DataTable/__tests__/TableExpandHeader-test.js
index 065a8ff1f189..52c0681d8a87 100644
--- a/packages/react/src/components/DataTable/__tests__/TableExpandHeader-test.js
+++ b/packages/react/src/components/DataTable/__tests__/TableExpandHeader-test.js
@@ -5,9 +5,24 @@
* LICENSE file in the root directory of this source tree.
*/
-import React from 'react';
+import React, { useState, useEffect } from 'react';
import { mount } from 'enzyme';
-import { Table, TableHead, TableRow, TableExpandHeader } from '../';
+import DataTable, {
+ Table,
+ TableHead,
+ TableHeader,
+ TableRow,
+ TableExpandHeader,
+ TableContainer,
+ TableBody,
+ TableExpandRow,
+ TableCell,
+ TableExpandedRow,
+} from '../';
+import { Pagination } from '../../../';
+import { rows, headers } from '../stories/shared';
+import { render, screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
describe('DataTable.TableExpandHeader', () => {
it('should render', () => {
@@ -28,3 +43,180 @@ describe('DataTable.TableExpandHeader', () => {
expect(wrapper).toMatchSnapshot();
});
});
+
+describe('TableExpandHeader', () => {
+ it('should call onExpand', () => {
+ const onExpand = jest.fn();
+ render(
+
+ {({
+ headers,
+ getTableProps,
+ getHeaderProps,
+ getExpandHeaderProps,
+ getTableContainerProps,
+ }) => (
+
+
+
+
+
+ {headers.map((header, i) => (
+
+ {header.header}
+
+ ))}
+
+
+
+
+ )}
+
+ );
+
+ userEvent.click(screen.getByRole('button'));
+
+ expect(onExpand).toHaveBeenCalled();
+ });
+
+ it('should update toggle button', () => {
+ const PaginationExample = () => {
+ const [rows, setRows] = useState([]);
+ const headers = [
+ {
+ key: 'value',
+ header: 'Value',
+ },
+ {
+ key: 'timestamp',
+ header: 'Submitted At',
+ },
+ ];
+
+ const allRows = [
+ {
+ id: 'f66f9f0e293e622b046ab4826f99d071a377418fd69bf1685c8d23c371f517cc',
+ value: 'First',
+ timestamp: '2022-06-06T12:57:27',
+ },
+ {
+ id: 'd0d95500fccef68dd1e7cb36f381984d340e9a81657b00e578ef175b195d4983',
+ value: 'Sewcond',
+ timestamp: '2022-06-06T12:57:27',
+ },
+ {
+ id: 'fad0a998e49fb8a9f5681f34f3288bea55559853d971c541607d22fd25773ed8',
+ value: 'third',
+ timestamp: '2022-06-06T12:57:27',
+ },
+ {
+ id: 'c8ad923e8b0ff106d104e95d695f84e695525364c0acdc74786e4c59a457c637',
+ value: 'Fourth',
+ timestamp: '2022-06-06T12:57:20',
+ },
+ {
+ id: '0f7b8a2912a59a737a6e7e1d3c4807d64ad0c8f54d383d9a118851f2c8f98ab6',
+ value: 'Fifth',
+ timestamp: '2022-06-06T12:57:21',
+ },
+ {
+ id: 'fad0a998e49fb8a9f5681f34f3288bea07659834a971c541607d22fd25773ed8',
+ value: 'Sixth',
+ timestamp: '2022-06-06T12:57:27',
+ },
+ ];
+
+ const paginate = ({ page, pageSize }) => {
+ const start = (page - 1) * pageSize;
+ const end = page * pageSize;
+ return allRows.slice(start, end);
+ };
+
+ useEffect(() => {
+ setRows(paginate({ page: 1, pageSize: 2 }));
+ }, []); // eslint-disable-line react-hooks/exhaustive-deps
+
+ return (
+ <>
+
+ {({
+ rows,
+ headers,
+ getTableProps,
+ getHeaderProps,
+ getRowProps,
+ getExpandHeaderProps,
+ }) => (
+
+
+
+
+ {headers.map((header) => (
+
+ {header.header}
+
+ ))}
+
+
+
+ {rows.map((row, index) => (
+
+
+ {row.cells.map((cell) => (
+ {cell.value}
+ ))}
+
+
+ Some content for {row.id}
+
+
+ ))}
+
+
+ )}
+
+ {
+ setRows(paginate({ page, pageSize }));
+ }}
+ page={1}
+ pageSize={2}
+ pageSizes={[2]}
+ size="md"
+ totalItems={allRows.length}
+ />
+ >
+ );
+ };
+
+ render();
+
+ userEvent.click(screen.getByLabelText('Expand all rows'));
+
+ expect(screen.getAllByRole('button')[0]).toHaveAttribute(
+ 'aria-label',
+ 'Collapse all rows'
+ );
+
+ userEvent.click(screen.getByLabelText('Next page'));
+ expect(screen.getAllByRole('button')[0]).toHaveAttribute(
+ 'aria-label',
+ 'Expand all rows'
+ );
+ });
+});
diff --git a/packages/react/src/components/DataTable/state/getDerivedStateFromProps.js b/packages/react/src/components/DataTable/state/getDerivedStateFromProps.js
index 3d151daea38d..573e4507d07e 100644
--- a/packages/react/src/components/DataTable/state/getDerivedStateFromProps.js
+++ b/packages/react/src/components/DataTable/state/getDerivedStateFromProps.js
@@ -47,6 +47,10 @@ const getDerivedStateFromProps = (props, prevState) => {
state.rowIds = rowIds;
}
+ state.isExpandedAll = state.rowIds.every((id) => {
+ return state.rowsById[id].isExpanded === true;
+ });
+
return state;
};
diff --git a/packages/react/src/components/DataTable/stories/expansion/DataTable-expansion.stories.js b/packages/react/src/components/DataTable/stories/expansion/DataTable-expansion.stories.js
index 850afe6bde80..7c45aeec778e 100644
--- a/packages/react/src/components/DataTable/stories/expansion/DataTable-expansion.stories.js
+++ b/packages/react/src/components/DataTable/stories/expansion/DataTable-expansion.stories.js
@@ -6,7 +6,7 @@
*/
import './DataTable-expansion-story.scss';
-import React from 'react';
+import React, { useState, useEffect } from 'react';
import DataTable, {
Table,
TableBody,
@@ -19,6 +19,7 @@ import DataTable, {
TableHeader,
TableRow,
} from '../..';
+import { Pagination } from '../../../../';
import { rows, headers } from '../shared';
import mdx from '../../DataTable.mdx';
@@ -147,6 +148,119 @@ export const BatchExpansion = () => (
/>
);
+// REMOVE BEFORE MERGE
+export const TestToggle = () => {
+ const [rows, setRows] = useState([]);
+ const headers = [
+ {
+ key: 'value',
+ header: 'Value',
+ },
+ {
+ key: 'timestamp',
+ header: 'Submitted At',
+ },
+ ];
+
+ const allRows = [
+ {
+ id: 'f66f9f0e293e622b046ab4826f99d071a377418fd69bf1685c8d23c371f517cc',
+ value: 'First',
+ timestamp: '2022-06-06T12:57:27',
+ },
+ {
+ id: 'd0d95500fccef68dd1e7cb36f381984d340e9a81657b00e578ef175b195d4983',
+ value: 'Sewcond',
+ timestamp: '2022-06-06T12:57:27',
+ },
+ {
+ id: 'fad0a998e49fb8a9f5681f34f3288bea55559853d971c541607d22fd25773ed8',
+ value: 'third',
+ timestamp: '2022-06-06T12:57:27',
+ },
+ {
+ id: 'c8ad923e8b0ff106d104e95d695f84e695525364c0acdc74786e4c59a457c637',
+ value: 'Fourth',
+ timestamp: '2022-06-06T12:57:20',
+ },
+ {
+ id: '0f7b8a2912a59a737a6e7e1d3c4807d64ad0c8f54d383d9a118851f2c8f98ab6',
+ value: 'Fifth',
+ timestamp: '2022-06-06T12:57:21',
+ },
+ {
+ id: 'fad0a998e49fb8a9f5681f34f3288bea07659834a971c541607d22fd25773ed8',
+ value: 'Sixth',
+ timestamp: '2022-06-06T12:57:27',
+ },
+ ];
+
+ const paginate = ({ page, pageSize }) => {
+ const start = (page - 1) * pageSize;
+ const end = page * pageSize;
+ return allRows.slice(start, end);
+ };
+
+ useEffect(() => {
+ setRows(paginate({ page: 1, pageSize: 2 }));
+ }, []); // eslint-disable-line react-hooks/exhaustive-deps
+
+ return (
+ <>
+
+ {({
+ rows,
+ headers,
+ getTableProps,
+ getHeaderProps,
+ getRowProps,
+ getExpandHeaderProps,
+ }) => (
+
+
+
+
+ {headers.map((header) => (
+
+ {header.header}
+
+ ))}
+
+
+
+ {rows.map((row, index) => (
+
+
+ {row.cells.map((cell) => (
+ {cell.value}
+ ))}
+
+
+ Some content for {row.id}
+
+
+ ))}
+
+
+ )}
+
+ {
+ setRows(paginate({ page, pageSize }));
+ }}
+ page={1}
+ pageSize={2}
+ pageSizes={[2]}
+ size="md"
+ totalItems={allRows.length}
+ />
+ >
+ );
+};
+
export const Playground = (args) => (
{({