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

Excluded sub-component id in newState when handling selection in Table #2317

Merged
merged 11 commits into from
Oct 30, 2024
5 changes: 5 additions & 0 deletions .changeset/strange-rockets-taste.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@itwin/itwinui-react': patch
---

Fixed duplicate data returned from the `onSelect` prop passed into `Table`.
38 changes: 38 additions & 0 deletions packages/itwinui-react/src/core/Table/Table.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1981,6 +1981,44 @@ it('should select and filter rows', async () => {
expect(checkboxInputs[3].checked).toBe(false);
});

it('should only select main row when subComponent is present', async () => {
const logSpy = vitest.spyOn(console, 'log');
const columns = [
{
id: 'name',
Header: 'Name',
accessor: 'name',
},
{
id: 'description',
Header: 'description',
accessor: 'description',
},
];

const data = mockedData();

const { container } = renderComponent({
columns,
data,
isSelectable: true,
onSelect: (selectedRows) => console.log(selectedRows),
subComponent: (row) => <div>{`Name ${row.original.name}`}</div>,
});

const checkboxCells = container.querySelectorAll('.iui-slot .iui-checkbox');
expect(checkboxCells.length).toBe(4);

await userEvent.click(checkboxCells[0]);
expect(logSpy).toHaveBeenCalledWith(data);

await userEvent.click(checkboxCells[1]);
expect(logSpy).toHaveBeenCalledWith([data[1], data[2]]);

await userEvent.click(checkboxCells[2]);
expect(logSpy).toHaveBeenCalledWith([data[2]]);
});

it('should pass custom props to row', () => {
const onMouseEnter = vi.fn();
let element: HTMLInputElement | null = null;
Expand Down
2 changes: 1 addition & 1 deletion packages/itwinui-react/src/core/Table/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ const singleRowSelectedAction = 'singleRowSelected';
const shiftRowSelectedAction = 'shiftRowSelected';
export const tableResizeStartAction = 'tableResizeStart';
const tableResizeEndAction = 'tableResizeEnd';
const iuiId = Symbol('iui-id');
export const iuiId = Symbol('iui-id');

export type TablePaginatorRendererProps = {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {
TableState,
IdType,
} from '../../../react-table/react-table.js';
import { iuiId } from '../Table.js';

/**
* Handles subrow selection and validation.
Expand Down Expand Up @@ -38,20 +39,24 @@ const onSelectHandler = <T extends Record<string, unknown>>(
}

let isAllSubSelected = true;
row.initialSubRows.forEach((subRow) => {
const result = handleRow(subRow);
if (!result) {
isAllSubSelected = false;
}
});

// If `selectSubRows` is false, then no need to select sub-rows and just check current selection state.
// If a row doesn't have sub-rows then check its selection state.
// If it has sub-rows then check whether all of them are selected.
if (row.initialSubRows[0]?.original[iuiId as any] === undefined) {
row.initialSubRows.forEach((subRow) => {
const result = handleRow(subRow);
if (!result) {
isAllSubSelected = false;
}
});
}

// A row is considered selected if it is selected AND one of the following:
// - `selectSubRows` is false, OR
// - the row has no sub-rows, OR
// - the row has sub-rows and all of them are selected
if (
(!instance.selectSubRows && newState.selectedRowIds[row.id]) ||
(!row.initialSubRows.length && newState.selectedRowIds[row.id]) ||
(row.initialSubRows.length && isAllSubSelected)
newState.selectedRowIds[row.id] &&
(!instance.selectSubRows ||
!row.initialSubRows.length ||
isAllSubSelected)
) {
newSelectedRowIds[row.id as IdType<T>] = true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type {
} from '../../../react-table/react-table.js';
import { Checkbox } from '../../Checkbox/Checkbox.js';
import { DefaultCell } from '../cells/index.js';
import { iuiId } from '../Table.js';

export const SELECTION_CELL_ID = 'iui-table-checkbox-selector';

Expand Down Expand Up @@ -82,7 +83,12 @@ export const SelectionColumn = <T extends Record<string, unknown>>(
disabled={isDisabled?.(row.original)}
onClick={(e) => e.stopPropagation()} // Prevents triggering on row click
onChange={() => {
if (row.subRows.length > 0 && selectSubRows) {
// Only goes through sub-rows if they are available and not sub-components
if (
row.subRows.length > 0 &&
selectSubRows &&
row.initialSubRows[0].original[iuiId as any] === undefined
) {
//This code ignores any sub-rows that are not currently available(i.e disabled or filtered out).
//If all available sub-rows are selected, then it deselects them all, otherwise it selects them all.
row.toggleRowSelected(
Expand Down
Loading