Skip to content

Commit

Permalink
test(Datagrid): add test coverage for new hook
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewgallo committed Nov 30, 2023
1 parent 370d06e commit 4c3a040
Show file tree
Hide file tree
Showing 12 changed files with 147 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,24 @@
td {
background: $layer-hover;
}

.#{variables.$block-class}
.#{c4p-settings.$carbon-prefix}--data-table
tbody
tr:hover
td.#{variables.$block-class}__expanded-row-cell-wrapper,
.#{variables.$block-class}
.#{c4p-settings.$carbon-prefix}--data-table
td.#{variables.$block-class}__expanded-row-cell-wrapper,
.#{variables.$block-class}
.#{c4p-settings.$carbon-prefix}--data-table
.#{variables.$block-class}__carbon-row-expanded
td.#{variables.$block-class}__expandable-row-cell {
border: none;
}

.#{variables.$block-class}
.#{c4p-settings.$carbon-prefix}--data-table
td.#{variables.$block-class}__expanded-row-cell-wrapper {
padding: 0;
}
31 changes: 19 additions & 12 deletions packages/ibm-products/src/components/Datagrid/Datagrid.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ const ExpandedRow = ({ ...rest } = {}) => {
useExpandedRow
);

return <Datagrid datagridState={{ ...datagridState }} {...rest} />;
return <Datagrid datagridState={datagridState} {...rest} />;
};

const SelectItemsInAllPages = ({ ...rest } = {}) => {
Expand Down Expand Up @@ -1434,37 +1434,44 @@ describe(componentName, () => {
fireEvent.click(clickableRow);
});

function clickRow(rowNumber) {
async function clickRow(rowNumber, triggerAnotherExpander) {
const user = userEvent.setup({ delay: null });
const { click, hover, unhover } = user;
const rows = screen.getAllByRole('row');
const bodyRows = rows.filter(
(r) =>
!r.classList.contains('c4p--datagrid__head') &&
!r.classList.contains('c4p--datagrid__expanded-row')
!r.classList.contains(`${pkg.prefix}--datagrid__head`) &&
!r.classList.contains(`${pkg.prefix}--datagrid__expanded-row`)
);
const row = bodyRows[rowNumber];

const rowExpander = row.querySelector(`button[aria-label="Expand row"]`);
fireEvent.click(rowExpander);
const rowExpander = within(row).getByLabelText('Expand row');
await click(rowExpander);

expect(row.nextElementSibling).toHaveClass(`${blockClass}__expanded-row`);
expect(row.nextElementSibling.textContent).toEqual(
`Content for ${rowNumber}`
);

fireEvent.mouseOver(row.nextElementSibling);
fireEvent.mouseLeave(row.nextElementSibling);
hover(row.nextElementSibling);
unhover(row.nextElementSibling);

const rowExpanderCollapse = row.querySelector(
`button[aria-label="Collapse row"]`
);
if (triggerAnotherExpander) {
const nextRow = bodyRows[rowNumber + 1];
const nextRowExpanderExpand =
within(nextRow).getByLabelText('Expand row');
fireEvent.click(nextRowExpanderExpand);
return;
}
const rowExpanderCollapse = within(row).getByLabelText('Collapse row');
fireEvent.click(rowExpanderCollapse);
}

it('should render with expandable rows and test by toggling the row open and closed', () => {
render(<ExpandedRow data-testid={dataTestId} />);
clickRow(1);
clickRow(4);
clickRow(8);
clickRow(8, true);
});

function hideSelectAll(rowNumber) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,16 @@ const DatagridExpandedRow =
onMouseEnter={(event) => toggleParentHoverClass(event, 'enter')}
onMouseLeave={(event) => toggleParentHoverClass(event)}
>
<div
className={`${blockClass}__expanded-row-content`}
style={{
height: expandedContentHeight && expandedContentHeight,
}}
>
<ExpandedRowContentComponent {...datagridState} />
</div>
<td className={`${blockClass}__expanded-row-cell-wrapper`}>
<div
className={`${blockClass}__expanded-row-content`}
style={{
height: expandedContentHeight && expandedContentHeight,
}}
>
<ExpandedRowContentComponent {...datagridState} />
</div>
</td>
</tr>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,15 @@ const rowHeights = {

// eslint-disable-next-line react/prop-types
const DatagridRow = (datagridState) => {
const { row, rowSize, withNestedRows, prepareRow, key } = datagridState;
const {
row,
rowSize,
withNestedRows,
prepareRow,
key,
tableId,
withExpandedRows,
} = datagridState;

const getVisibleNestedRowCount = ({ isExpanded, subRows }) => {
let size = 0;
Expand Down Expand Up @@ -67,7 +75,7 @@ const DatagridRow = (datagridState) => {

const focusRemover = () => {
const elements = document.querySelectorAll(
`.${blockClass}__carbon-row-expanded`
`#${tableId} .${blockClass}__carbon-row-expanded`
);
elements.forEach((el) => {
el.classList.remove(`${blockClass}__carbon-row-expanded-hover-active`);
Expand Down Expand Up @@ -107,6 +115,15 @@ const DatagridRow = (datagridState) => {
[`${carbon.prefix}--data-table--selected`]: row.isSelected,
});

const setAdditionalRowProps = () => {
if (withNestedRows || withExpandedRows) {
return {
'data-nested-row-id': row.id,
};
}
return {};
};

return (
<React.Fragment key={key}>
<TableRow
Expand All @@ -118,6 +135,7 @@ const DatagridRow = (datagridState) => {
onFocus={hoverHandler}
onBlur={focusRemover}
onKeyUp={handleOnKeyUp}
{...setAdditionalRowProps()}
>
{row.cells.map((cell, index) => {
const cellProps = cell.getCellProps();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import { DatagridActions } from '../../utils/DatagridActions';
import { DatagridPagination } from '../../utils/DatagridPagination';
import { makeData } from '../../utils/makeData';
import { ARG_TYPES } from '../../utils/getArgTypes';
import { pkg } from '../../../../settings';
import { DocsPage } from './ExpandableRow.docs-page';
import { usePrefix } from '../../../../global/js/hooks';

Expand Down Expand Up @@ -189,12 +188,6 @@ const ExpandedRows = ({ ...args }) => {
useExpandedRow
);

// Warnings are ordinarily silenced in storybook, add this to test.
pkg._silenceWarnings(false);
// Enable feature flag for `useExpandedRow` hook
pkg.feature['Datagrid.useExpandedRow'] = true;
pkg._silenceWarnings(true);

return <Datagrid datagridState={datagridState} />;
};

Expand Down Expand Up @@ -222,6 +215,5 @@ export const ExpandableRowStory = prepareStory(BasicTemplateWrapper, {
},
args: {
...expandableRowControlProps,
featureFlags: ['Datagrid.useExpandedRow'],
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@ import {
} from '../../../../global/js/utils/story-helper';
import { Datagrid, useDatagrid, useNestedRows } from '../../index';
import styles from '../../_storybook-styles.scss';
// import mdx from '../../Datagrid.mdx';
import { DatagridActions } from '../../utils/DatagridActions';
import { makeData } from '../../utils/makeData';
import { ARG_TYPES } from '../../utils/getArgTypes';
import { pkg } from '../../../../settings';
import { StoryDocsPage } from '../../../../global/js/utils/StoryDocsPage';

export default {
Expand Down Expand Up @@ -205,12 +203,6 @@ const SingleLevelNestedRows = ({ ...args }) => {
useNestedRows
);

// Warnings are ordinarily silenced in storybook, add this to test
pkg._silenceWarnings(false);
// Enable feature flag for `useNestedRows` hook
pkg.feature['Datagrid.useNestedRows'] = true;
pkg._silenceWarnings(true);

return <Datagrid datagridState={{ ...datagridState }} />;
};

Expand Down Expand Up @@ -253,12 +245,6 @@ const NestedRows = ({ ...args }) => {
useNestedRows
);

// Warnings are ordinarily silenced in storybook, add this to test
pkg._silenceWarnings(false);
// Enable feature flag for `useNestedRows` hook
pkg.feature['Datagrid.useNestedRows'] = true;
pkg._silenceWarnings(true);

return <Datagrid datagridState={{ ...datagridState }} />;
};

Expand All @@ -281,6 +267,5 @@ export const NestedRowsUsageStory = prepareStory(BasicTemplateWrapper, {
},
args: {
...nestedRowsControlProps,
featureFlags: ['Datagrid.useNestedRows'],
},
});
13 changes: 6 additions & 7 deletions packages/ibm-products/src/components/Datagrid/useExpandedRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,11 @@
* LICENSE file in the root directory of this source tree.
*/

import { useEffect, useState } from 'react';
import { pkg } from '../../settings';
import { useState } from 'react';
import DatagridExpandedRow from './Datagrid/DatagridExpandedRow';
import useRowExpander from './useRowExpander';

const useExpandedRow = (hooks) => {
useEffect(() => {
pkg.checkReportFeatureEnabled('Datagrid.useExpandedRow');
}, []);

useRowExpander(hooks);
const useInstance = (instance) => {
const { rows, expandedContentHeight, ExpandedRowContentComponent } =
Expand All @@ -29,7 +24,11 @@ const useExpandedRow = (hooks) => {
expandedRowsHeight[row.index] || expandedContentHeight,
RowExpansionRenderer: DatagridExpandedRow(ExpandedRowContentComponent),
}));
Object.assign(instance, { rows: rowsWithExpand, setExpandedRowHeight });
Object.assign(instance, {
rows: rowsWithExpand,
setExpandedRowHeight,
withExpandedRows: true,
});
};
hooks.useInstance.push(useInstance);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* Copyright IBM Corp. 2023, 2023
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import { useEffect } from 'react';

// Focuses the row expander after a nested/expandable row state change.
// We have to add this workaround because react-table is re-rendering the entire row
// which removes the focus from the expander and interrupts the keyboard navigation
// flow.
export const useFocusRowExpander = ({
instance,
lastExpandedRowIndex = 0,
blockClass,
activeElement,
}) => {
useEffect(() => {
// We need to return at this point so that the focus is not stolen from
// other interactive elements in the Datagrid
if (!activeElement.classList.contains(`${blockClass}__row-expander`)) {
return;
}
const tableId = instance?.tableId;
const rowElements = document.querySelectorAll(`#${tableId} tbody tr`);
const rowElementsArray = Array.from(rowElements);
const activeRow = rowElementsArray.filter((r) => {
if (r.getAttribute('data-nested-row-id') === lastExpandedRowIndex) {
return r;
}
return null;
});
if (activeRow.length) {
const rowExpander = activeRow[0].querySelector(
`.${blockClass}__row-expander`
);
rowExpander.focus();
}
}, [
instance?.tableId,
instance?.expandedRows,
lastExpandedRowIndex,
blockClass,
activeElement,
]);
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,24 @@ import React, { useRef } from 'react';
import { ChevronRight } from '@carbon/react/icons';
import cx from 'classnames';
import { pkg, carbon } from '../../settings';
import { useFocusRowExpander } from './useFocusRowExpander';

const blockClass = `${pkg.prefix}--datagrid`;

const useNestedRowExpander = (hooks) => {
const tempState = useRef();
const lastExpandedRowIndex = useRef();
const useInstance = (instance) => {
tempState.current = instance;
};

useFocusRowExpander({
instance: tempState?.current,
lastExpandedRowIndex: lastExpandedRowIndex?.current,
blockClass,
activeElement: document.activeElement,
});

const visibleColumns = (columns) => {
const expanderColumn = {
id: 'expander',
Expand All @@ -28,6 +38,7 @@ const useNestedRowExpander = (hooks) => {
// Prevents `onRowClick` from being called if `useOnRowClick` is included
event.stopPropagation();
row.toggleRowExpanded();
lastExpandedRowIndex.current = row.id;
},
};
const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,13 @@
* LICENSE file in the root directory of this source tree.
*/

import { useEffect } from 'react';
import { pkg } from '../../settings';
import cx from 'classnames';
import { pkg } from '../../settings';
import useNestedRowExpander from './useNestedRowExpander';

const blockClass = `${pkg.prefix}--datagrid`;

const useNestedRows = (hooks) => {
useEffect(() => {
pkg.checkReportFeatureEnabled('Datagrid.useNestedRows');
}, []);

useNestedRowExpander(hooks);
const marginLeft = 24;

Expand Down
Loading

0 comments on commit 4c3a040

Please sign in to comment.