Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(Datagrid): add test coverage for new hook #3879

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL 😳

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
Loading