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

Fixed expandable content does not work when using enableVirtualization in Table #2208

Merged
merged 76 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from 64 commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
174cb8a
fixed virtualization bug in subComponent
smmr-dn Aug 23, 2024
048b07b
revert App.tsx
smmr-dn Aug 23, 2024
f940be2
removed comments
smmr-dn Aug 26, 2024
d146051
Merge branch 'main' into uyen/virtualization-bug
smmr-dn Aug 26, 2024
34691cc
added copyright
smmr-dn Aug 26, 2024
80e01d4
Merge branch 'main' of https://github.com/iTwin/iTwinUI into uyen/vir…
smmr-dn Aug 26, 2024
71e2ecf
Merge branch 'uyen/virtualization-bug' of https://github.com/iTwin/iT…
smmr-dn Aug 26, 2024
c4fb099
changeset
smmr-dn Aug 26, 2024
7defb0b
fixed conditional render
smmr-dn Aug 27, 2024
002b797
Merge branch 'main' into uyen/virtualization-bug
smmr-dn Aug 27, 2024
efd421e
removed comments and revert App.tsx
smmr-dn Aug 27, 2024
a863250
Merge branch 'uyen/virtualization-bug' of https://github.com/iTwin/iT…
smmr-dn Aug 27, 2024
b90a8f2
used forwardRef
smmr-dn Aug 27, 2024
2dbe864
gave preference to user-defined getSubRows
smmr-dn Aug 27, 2024
29de7bb
comments
smmr-dn Aug 28, 2024
afadb69
removed objectified props
smmr-dn Aug 28, 2024
246db41
put back flex setup
smmr-dn Aug 28, 2024
b343fa4
Merge branch 'main' into uyen/virtualization-bug
smmr-dn Aug 28, 2024
fb37713
Merge branch 'main' into uyen/virtualization-bug
smmr-dn Aug 29, 2024
e7c0080
switched to approaching indices
smmr-dn Aug 30, 2024
7d0dfa6
Merge branch 'uyen/virtualization-bug' of https://github.com/iTwin/iT…
smmr-dn Aug 30, 2024
2fa81d3
Merge branch 'main' into uyen/virtualization-bug
smmr-dn Sep 3, 2024
844bf03
explicitly told virtualItem to measureElement
smmr-dn Sep 3, 2024
371e848
Merge branch 'uyen/virtualization-bug' of https://github.com/iTwin/iT…
smmr-dn Sep 3, 2024
31c31a6
fixed virtualized subrow error
smmr-dn Sep 4, 2024
24de052
cleaned up
smmr-dn Sep 4, 2024
1720e9a
Merge branch 'main' into uyen/virtualization-bug
smmr-dn Sep 4, 2024
86b5ed2
added e2e tests for expandable rows
smmr-dn Sep 4, 2024
aeb634d
cleaned up
smmr-dn Sep 4, 2024
d318c88
small fixes:
smmr-dn Sep 5, 2024
2e15f14
Delete playgrounds/vite/src/App.tsx
smmr-dn Sep 5, 2024
c626a6a
revert App.tsx
smmr-dn Sep 5, 2024
387b83e
revert App.tsx
smmr-dn Sep 5, 2024
edfe017
Merge branch 'main' into uyen/virtualization-bug
smmr-dn Sep 6, 2024
f09f14d
Merge branch 'main' into uyen/virtualization-bug
smmr-dn Sep 6, 2024
bda7809
Merge branch 'main' into uyen/virtualization-bug
smmr-dn Sep 10, 2024
2c0da60
Merge branch 'main' into uyen/virtualization-bug
smmr-dn Sep 11, 2024
a76d020
moved virtualization related functions into custom hook
smmr-dn Sep 11, 2024
645dba6
added copyright
smmr-dn Sep 11, 2024
eff83a6
removed unnecessary vars
smmr-dn Sep 12, 2024
7aa71b1
wording
smmr-dn Sep 12, 2024
ff9e1ad
Merge branch 'main' into uyen/virtualization-bug
smmr-dn Sep 13, 2024
7e12320
Merge branch 'main' of https://github.com/iTwin/iTwinUI into uyen/vir…
smmr-dn Sep 13, 2024
46d1d97
merged main
smmr-dn Sep 13, 2024
89b2e0d
Merge branch 'uyen/virtualization-bug' of https://github.com/iTwin/iT…
smmr-dn Sep 13, 2024
c174e9a
Merge branch 'main' into uyen/virtualization-bug
smmr-dn Sep 16, 2024
83a00a7
Merge branch 'main' into uyen/virtualization-bug
smmr-dn Sep 17, 2024
00e8a23
switched back to getSubRows
smmr-dn Sep 17, 2024
96c527f
Merge branch 'uyen/virtualization-bug' of https://github.com/iTwin/iT…
smmr-dn Sep 17, 2024
4963252
removed redundant hook export
smmr-dn Sep 17, 2024
ac2bd7b
cleaned up
smmr-dn Sep 17, 2024
682dfa9
cleaned up
smmr-dn Sep 17, 2024
eef02fd
cleaned up
smmr-dn Sep 17, 2024
c3c56b4
cleaned up
smmr-dn Sep 17, 2024
83f4aae
added key
smmr-dn Sep 17, 2024
2051007
cleaned up
smmr-dn Sep 17, 2024
250da0f
revert App.tsx
smmr-dn Sep 17, 2024
5d60691
fixed unit test
smmr-dn Sep 17, 2024
d6d5d65
added comment
smmr-dn Sep 17, 2024
4aa1bbb
Merge branch 'main' into uyen/virtualization-bug
smmr-dn Sep 17, 2024
9ccaed4
fixed e2e test
smmr-dn Sep 17, 2024
52ee6da
Merge branch 'uyen/virtualization-bug' of https://github.com/iTwin/iT…
smmr-dn Sep 17, 2024
72d5380
tested e2e test
smmr-dn Sep 17, 2024
0ae6809
added more cases
smmr-dn Sep 17, 2024
8d44889
Merge branch 'main' into uyen/virtualization-bug
smmr-dn Sep 18, 2024
6e373c5
small logic fixes
smmr-dn Sep 18, 2024
fdab0ce
Merge branch 'main' into uyen/virtualization-bug
smmr-dn Sep 18, 2024
23e6da7
switched to using WeakSet
smmr-dn Sep 18, 2024
b8c1825
Merge branch 'uyen/virtualization-bug' of https://github.com/iTwin/iT…
smmr-dn Sep 18, 2024
921570f
Merge branch 'main' into uyen/virtualization-bug
smmr-dn Sep 18, 2024
4eded6a
added changeset for withcsstransition
smmr-dn Sep 19, 2024
213ad15
Update short-planets-listen.md
smmr-dn Sep 19, 2024
3be47ef
Update short-planets-listen.md
smmr-dn Sep 19, 2024
8106b51
Merge branch 'main' into uyen/virtualization-bug
smmr-dn Sep 19, 2024
3ebf5d5
Merge branch 'main' into uyen/virtualization-bug
smmr-dn Sep 19, 2024
c76b854
Merge branch 'main' into uyen/virtualization-bug
smmr-dn Sep 19, 2024
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
5 changes: 5 additions & 0 deletions .changeset/lucky-suits-decide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@itwin/itwinui-react': patch
---

Fixed broken `subComponent` when enabling virtualization in `Table`.
2 changes: 1 addition & 1 deletion packages/itwinui-react/src/core/Table/Table.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2040,7 +2040,7 @@ it('should render sub-rows and handle expansions', async () => {
expect(onExpand).toHaveBeenNthCalledWith(1, [data[0]], expect.any(Object));
expect(onExpand).toHaveBeenNthCalledWith(
2,
[data[0], data[0].subRows[1]],
[data[0], data[1]],
mayank99 marked this conversation as resolved.
Show resolved Hide resolved
expect.any(Object),
);
expect(onExpand).toHaveBeenNthCalledWith(
Expand Down
50 changes: 36 additions & 14 deletions packages/itwinui-react/src/core/Table/Table.tsx
mayank99 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ import {
useMergedRefs,
useLatestRef,
useVirtualScroll,
WithCSSTransition,
} from '../../utils/index.js';
import type { CommonProps } from '../../utils/index.js';
import { TableColumnsContext } from './utils.js';
Expand All @@ -65,7 +64,7 @@ import {
onTableResizeStart,
} from './actionHandlers/index.js';
import { SELECTION_CELL_ID } from './columns/index.js';
import { Virtualizer, type VirtualItem } from '@tanstack/react-virtual';
import type { VirtualItem, Virtualizer } from '@tanstack/react-virtual';
import { ColumnHeader } from './ColumnHeader.js';
import { TableExpandableContentMemoized } from './TableExpandableContentMemoized.js';

Expand Down Expand Up @@ -580,6 +579,20 @@ export const Table = <
);
}, [data, getSubRows]);

const [rowHasParent] = React.useState(() => new Set<T>());

const getSubRowsWithSubComponents = React.useCallback(
(originalRow: T) => {
if (!rowHasParent.has(originalRow)) {
rowHasParent.add(originalRow);
mayank99 marked this conversation as resolved.
Show resolved Hide resolved
return [originalRow];
}

return (originalRow.subRows as T[]) || [];
},
[rowHasParent],
);

const instance = useTable<T>(
{
manualPagination: !paginatorRenderer, // Prevents from paginating rows in regular table without pagination
Expand All @@ -592,7 +605,7 @@ export const Table = <
filterTypes,
selectSubRows,
data,
getSubRows,
getSubRows: (subComponent && getSubRowsWithSubComponents) ?? getSubRows,
mayank99 marked this conversation as resolved.
Show resolved Hide resolved
r100-stack marked this conversation as resolved.
Show resolved Hide resolved
initialState: { pageSize, ...props.initialState },
columnResizeMode,
},
Expand Down Expand Up @@ -836,8 +849,9 @@ export const Table = <
) => {
const row = page[index];
prepareRow(row);
return (
<>

if (row.subRows.length > 0 || !subComponent) {
return (
<TableRowMemoized
row={row}
rowProps={rowProps}
Expand All @@ -859,24 +873,34 @@ export const Table = <
virtualItem={virtualItem}
virtualizer={virtualizer}
/>
{subComponent && (
<WithCSSTransition in={row.isExpanded}>
r100-stack marked this conversation as resolved.
Show resolved Hide resolved
);
} else {
return (
<>
{subComponent && (
r100-stack marked this conversation as resolved.
Show resolved Hide resolved
<TableExpandableContentMemoized
key={row.getRowProps().key}
ref={tableRowRef(row)}
virtualItem={virtualItem}
ref={
enableVirtualization
? virtualizer?.measureElement
: tableRowRef(row)
}
isDisabled={!!isRowDisabled?.(row.original)}
>
{subComponent(row)}
</TableExpandableContentMemoized>
</WithCSSTransition>
)}
</>
);
)}
</>
);
}
},
[
page,
prepareRow,
rowProps,
onRowInViewportRef,
onBottomReachedRef,
intersectionMargin,
state,
onRowClickHandler,
Expand All @@ -888,8 +912,6 @@ export const Table = <
enableVirtualization,
tableRowRef,
density,
onBottomReachedRef,
onRowInViewportRef,
],
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,31 @@ import cx from 'classnames';
import * as React from 'react';
import { Box } from '../../utils/index.js';
import type { PolymorphicForwardRefComponent } from '../../utils/index.js';
import type { VirtualItem } from '@tanstack/react-virtual';

type TableExpandableContentProps = {
children: React.ReactNode;
virtualItem?: VirtualItem<Element>;
isDisabled?: boolean;
};

const TableExpandableContent = React.forwardRef((props, ref) => {
const { children, className, style, isDisabled, ...rest } = props;
const { children, className, style, isDisabled, virtualItem, ...rest } =
props;
return (
<Box
className={cx('iui-table-row', 'iui-table-expanded-content', className)}
style={{
flex: '0 0 auto',
minWidth: '100%',
...(virtualItem != null
? { transform: `translateY(${virtualItem.start}px)` }
: {}),
...style,
}}
aria-disabled={isDisabled}
data-iui-index={virtualItem?.index}
{...(virtualItem != null && { 'data-iui-virtualizer': 'item' })}
ref={ref}
{...rest}
>
Expand Down
8 changes: 8 additions & 0 deletions testing/e2e/app/routes/Table/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ function EverythingElse() {
const oneRow = searchParams.get('oneRow') === 'true';
const stateReducer = searchParams.get('stateReducer') === 'true';
const scrollRow = Number(searchParams.get('scrollRow'));
const hasSubComponent = searchParams.get('hasSubComponent') === 'true';

const virtualizedData = React.useMemo(() => {
const size = oneRow ? 1 : 100000;
Expand Down Expand Up @@ -162,6 +163,13 @@ function EverythingElse() {
}
: undefined
}
subComponent={
hasSubComponent
? (row) => (
<div>{`Expanded component, name: ${row.original.name}`}</div>
)
: undefined
}
/>
</>
);
Expand Down
44 changes: 44 additions & 0 deletions testing/e2e/app/routes/Table/spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,50 @@ test.describe('Virtual Scroll Tests', () => {
const rows = page.getByRole('rowgroup').getByRole('row');
expect((await rows.all()).length).toBe(1);
});

test('virtualized table should allow expandable contents', async ({
page,
}) => {
await page.goto(
'/Table?virtualization=true&scroll=true&scrollRow=50&hasSubComponent=true',
{
waitUntil: 'networkidle',
},
); //Need to wait until the virtual rows are able to be rendered for the tests to work.

const rows = page.getByRole('rowgroup').getByRole('row');
await expect(rows.nth(1)).toContainText('Name50');
await expect(rows.nth(4)).toContainText('Name53');

const row50ExpanderContent = page.getByText(
'Expanded component, name: Name50',
);
const row53ExpanderContent = page.getByText(
'Expanded component, name: Name53',
);

const expanderButtonRow50Cell = rows
.nth(1)
.getByRole('cell')
.nth(0)
.getByRole('button');
const expanderButtonRow53Cell = rows
.nth(4)
.getByRole('cell')
.nth(0)
.getByRole('button');

await expanderButtonRow50Cell.click();
await expanderButtonRow53Cell.click();
await expect(row50ExpanderContent).toBeInViewport();
await expect(row53ExpanderContent).toBeInViewport();

// Collapse the expanded content
await expanderButtonRow50Cell.click();
await expect(row50ExpanderContent).not.toBeInViewport();
await expanderButtonRow53Cell.click();
await expect(row53ExpanderContent).not.toBeInViewport();
});
});

test.describe('Table filters', () => {
Expand Down
2 changes: 1 addition & 1 deletion testing/e2e/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { defineConfig, devices } from '@playwright/test';
*/
export default defineConfig({
testMatch: 'app/**/*spec.ts', // Look for test files anywhere in the app

timeout: 100000, // Increase timeout to 100s
fullyParallel: true, // Run tests in files in parallel
forbidOnly: !!process.env.CI, // Fail CI if you accidentally left test.only
retries: process.env.CI ? 2 : 0, // Retry on CI only
Expand Down
Loading