Skip to content

Commit b053c1d

Browse files
fix(AnalyticalTable): update @tanstack/react-virtual to 3.0.0-beta.61 (#4899)
Co-authored-by: Lukas Harbarth <[email protected]>
1 parent b0da979 commit b053c1d

File tree

15 files changed

+134
-152
lines changed

15 files changed

+134
-152
lines changed

packages/main/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
"watch:css": "postcss --watch --dir ../../temp src/**/*.css"
5353
},
5454
"dependencies": {
55-
"@tanstack/react-virtual": "3.0.0-beta.18",
55+
"@tanstack/react-virtual": "3.0.0-beta.61",
5656
"@ui5/webcomponents-react-base": "workspace:~",
5757
"clsx": "2.0.0",
5858
"react-jss": "^10.10.0",

packages/main/src/components/AnalyticalTable/AnalyticalTable.cy.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1884,12 +1884,14 @@ describe('AnalyticalTable', () => {
18841884
});
18851885
cy.get('[data-component-name="AnalyticalTableBody"]').scrollTo('bottom');
18861886
cy.findByText('X').trigger('keydown', {
1887-
key: 'Enter'
1887+
key: 'Enter',
1888+
force: true
18881889
});
18891890
cy.get('[data-component-name="AnalyticalTableBody"]').invoke('scrollTop').should('not.equal', 0);
18901891
cy.get('[data-component-name="AnalyticalTableBody"]').scrollTo('bottom');
18911892
cy.findByText('X').trigger('keydown', {
1892-
key: 'Enter'
1893+
key: 'Enter',
1894+
force: true
18931895
});
18941896
cy.get('[data-component-name="AnalyticalTableBody"]').invoke('scrollTop').should('not.equal', 0);
18951897
});
@@ -2294,7 +2296,7 @@ describe('AnalyticalTable', () => {
22942296
// last currently rendered row
22952297
cy.focused().should('have.attr', 'data-row-index', '22').should('have.attr', 'data-column-index', '0');
22962298
cy.realPress('PageDown');
2297-
cy.focused().should('have.attr', 'data-row-index', '36').should('have.attr', 'data-column-index', '0');
2299+
cy.focused().should('have.attr', 'data-row-index', '37').should('have.attr', 'data-column-index', '0');
22982300
cy.realPress('PageDown');
22992301
cy.focused().should('have.attr', 'data-row-index', '50').should('have.attr', 'data-column-index', '0');
23002302
cy.realPress('PageUp');

packages/main/src/components/AnalyticalTable/AnayticalTable.jss.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ const styles = {
104104
overflowY: 'auto',
105105
scrollbarWidth: 'none',
106106
borderBlockEnd: `1px solid ${ThemingParameters.sapList_TableFooterBorder}`,
107+
boxSizing: 'border-box',
107108
'-ms-overflow-style': 'none',
108109
'&::-webkit-scrollbar': {
109110
width: '0 !important',

packages/main/src/components/AnalyticalTable/ColumnHeader/ColumnHeaderContainer.tsx

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { VirtualItem, Virtualizer } from '@tanstack/react-virtual';
1+
import type { Virtualizer } from '@tanstack/react-virtual';
22
import { ThemingParameters } from '@ui5/webcomponents-react-base';
33
import React, { forwardRef, Fragment } from 'react';
44
import { createUseStyles } from 'react-jss';
@@ -23,20 +23,14 @@ const styles = {
2323

2424
interface ColumnHeaderContainerProps {
2525
headerProps: Record<string, unknown>;
26+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
2627
headerGroup: Record<string, any>;
2728
onSort: (e: CustomEvent<{ column: unknown; sortDirection: string }>) => void;
2829
onGroupByChanged: (e: CustomEvent<{ column?: Record<string, unknown>; isGrouped?: boolean }>) => void;
29-
onDragStart: any;
30-
onDragOver: any;
31-
onDrop: any;
32-
onDragEnter: any;
33-
onDragEnd: any;
34-
dragOver: any;
3530
resizeInfo: Record<string, unknown>;
3631
isRtl: boolean;
3732
portalContainer: Element;
38-
columnVirtualizer: Virtualizer<DivWithCustomScrollProp>;
39-
scaleXFactor?: number;
33+
columnVirtualizer: Virtualizer<DivWithCustomScrollProp, Element>;
4034
uniqueId: string;
4135
showVerticalEndBorder: boolean;
4236
}
@@ -49,17 +43,10 @@ export const ColumnHeaderContainer = forwardRef<HTMLDivElement, ColumnHeaderCont
4943
headerGroup,
5044
onSort,
5145
onGroupByChanged,
52-
onDragStart,
53-
onDragOver,
54-
onDrop,
55-
onDragEnter,
56-
onDragEnd,
57-
dragOver,
5846
resizeInfo,
5947
isRtl,
6048
portalContainer,
6149
columnVirtualizer,
62-
scaleXFactor,
6350
uniqueId,
6451
showVerticalEndBorder
6552
} = props;
@@ -73,7 +60,7 @@ export const ColumnHeaderContainer = forwardRef<HTMLDivElement, ColumnHeaderCont
7360
ref={ref}
7461
data-component-name="AnalyticalTableHeaderRow"
7562
>
76-
{columnVirtualizer.getVirtualItems().map((virtualColumn: VirtualItem<Record<string, unknown>>, index) => {
63+
{columnVirtualizer.getVirtualItems().map((virtualColumn, index) => {
7764
const column = headerGroup.headers[virtualColumn.index];
7865
if (!column) {
7966
return null;
@@ -106,21 +93,14 @@ export const ColumnHeaderContainer = forwardRef<HTMLDivElement, ColumnHeaderCont
10693
id={`${uniqueId}${rest?.id ?? ''}`}
10794
columnId={rest.id}
10895
visibleColumnIndex={index}
109-
columnIndex={virtualColumn.index}
11096
onSort={onSort}
11197
onGroupBy={onGroupByChanged}
112-
onDragStart={onDragStart}
113-
onDragOver={onDragOver}
114-
onDrop={onDrop}
115-
onDragEnter={onDragEnter}
116-
onDragEnd={onDragEnd}
117-
dragOver={column.id === dragOver}
11898
headerTooltip={column.headerTooltip}
11999
isDraggable={(column.canReorder || !column.disableDragAndDrop) && !resizeInfo.isResizingColumn}
120100
virtualColumn={virtualColumn}
101+
columnVirtualizer={columnVirtualizer}
121102
isRtl={isRtl}
122103
portalContainer={portalContainer}
123-
scaleXFactor={scaleXFactor}
124104
>
125105
{column.render('Header')}
126106
</ColumnHeader>

packages/main/src/components/AnalyticalTable/ColumnHeader/index.tsx

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { VirtualItem } from '@tanstack/react-virtual';
1+
import type { VirtualItem, Virtualizer } from '@tanstack/react-virtual';
22
import iconFilter from '@ui5/webcomponents-icons/dist/filter.js';
33
import iconGroup from '@ui5/webcomponents-icons/dist/group-2.js';
44
import iconSortAscending from '@ui5/webcomponents-icons/dist/sort-ascending.js';
@@ -18,12 +18,12 @@ import { createUseStyles } from 'react-jss';
1818
import { CustomThemingParameters } from '../../../themes/CustomVariables.js';
1919
import { Icon } from '../../../webComponents/Icon/index.js';
2020
import { Text } from '../../Text/index.js';
21+
import type { DivWithCustomScrollProp } from '../index.js';
2122
import type { ColumnType } from '../types/ColumnType.js';
2223
import { ColumnHeaderModal } from './ColumnHeaderModal.js';
2324

2425
export interface ColumnHeaderProps {
2526
visibleColumnIndex: number;
26-
columnIndex: number;
2727
onSort?: (e: CustomEvent<{ column: unknown; sortDirection: string }>) => void;
2828
onGroupBy?: (e: CustomEvent<{ column: unknown; isGrouped: boolean }>) => void;
2929
onDragStart: DragEventHandler<HTMLDivElement>;
@@ -34,11 +34,11 @@ export interface ColumnHeaderProps {
3434
dragOver: boolean;
3535
isDraggable: boolean;
3636
headerTooltip: string;
37-
virtualColumn: VirtualItem<Record<string, any>>;
37+
virtualColumn: VirtualItem;
38+
columnVirtualizer: Virtualizer<DivWithCustomScrollProp, Element>;
3839
isRtl: boolean;
3940
children: ReactNode | ReactNode[];
4041
portalContainer: Element;
41-
scaleXFactor?: number;
4242
columnId?: string;
4343
showVerticalEndBorder: boolean;
4444

@@ -135,20 +135,21 @@ export const ColumnHeader = (props: ColumnHeaderProps) => {
135135
dragOver,
136136
role,
137137
virtualColumn,
138+
columnVirtualizer,
138139
isRtl,
139-
columnIndex,
140140
visibleColumnIndex,
141141
onClick,
142142
onKeyDown,
143143
portalContainer,
144-
scaleXFactor,
145144
isFiltered,
146145
title,
147146
'aria-label': ariaLabel,
148147
'aria-sort': ariaSort,
149148
showVerticalEndBorder
150149
} = props;
151150

151+
const columnIndex = virtualColumn.index;
152+
152153
const [popoverOpen, setPopoverOpen] = useState(false);
153154
const columnHeaderRef = useRef<HTMLDivElement>(null);
154155

@@ -227,16 +228,7 @@ export const ColumnHeader = (props: ColumnHeaderProps) => {
227228
}}
228229
>
229230
<div
230-
ref={(node) => {
231-
const clientRect = node?.getBoundingClientRect();
232-
if (clientRect && scaleXFactor > 0) {
233-
const scaledGetBoundingClientRect = () => ({ ...clientRect, width: clientRect.width / scaleXFactor });
234-
const updatedNode = { ...node, getBoundingClientRect: scaledGetBoundingClientRect };
235-
virtualColumn.measureElement(updatedNode);
236-
} else {
237-
virtualColumn.measureElement(node);
238-
}
239-
}}
231+
ref={columnVirtualizer.measureElement}
240232
data-visible-column-index={visibleColumnIndex}
241233
data-visible-row-index={0}
242234
data-row-index={0}

packages/main/src/components/AnalyticalTable/TableBody/EmptyRow.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export const EmptyRow = ({
77
className,
88
children
99
}: {
10-
virtualRow: VirtualItem<any>;
10+
virtualRow: VirtualItem;
1111
className: string;
1212
children?: ReactNode;
1313
}) => {

packages/main/src/components/AnalyticalTable/TableBody/RowSubComponent.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const useStyles = createUseStyles(styles, { name: 'RowSubComponent' });
1818

1919
interface RowSubComponent {
2020
subComponentsHeight: Record<string, { rowId: string; subComponentHeight?: number }>;
21-
virtualRow: VirtualItem<Record<string, unknown>>;
21+
virtualRow: VirtualItem;
2222
dispatch: (e: { type: string; payload?: Record<string, unknown> }) => void;
2323
row: Record<string, unknown>;
2424
rowHeight: number;

packages/main/src/components/AnalyticalTable/TableBody/VirtualTableBody.tsx

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
import type { Virtualizer } from '@tanstack/react-virtual';
12
import { useVirtualizer } from '@tanstack/react-virtual';
23
import { clsx } from 'clsx';
34
import type { MutableRefObject, ReactNode } from 'react';
45
import React, { useCallback, useMemo, useRef } from 'react';
5-
import type { AnalyticalTablePropTypes } from '../index.js';
6+
import type { AnalyticalTablePropTypes, DivWithCustomScrollProp } from '../index.js';
67
import type { ScrollToRefType } from '../interfaces.js';
78
import { getSubRowsByString } from '../util/index.js';
89
import { EmptyRow } from './EmptyRow.js';
@@ -28,13 +29,15 @@ interface VirtualTableBodyProps {
2829
alwaysShowSubComponent: boolean;
2930
dispatch?: (e: { type: string; payload?: Record<string, unknown> }) => void;
3031
subComponentsHeight?: Record<string, { rowId: string; subComponentHeight?: number }>;
31-
columnVirtualizer: Record<string, any>;
32+
columnVirtualizer: Virtualizer<DivWithCustomScrollProp, Element>;
3233
manualGroupBy?: boolean;
3334
subRowsKey: string;
3435
scrollContainerRef?: MutableRefObject<HTMLDivElement>;
3536
}
3637

37-
const measureElement = (el) => el.offsetHeight;
38+
const measureElement = (el: HTMLElement) => {
39+
return el.offsetHeight;
40+
};
3841

3942
export const VirtualTableBody = (props: VirtualTableBodyProps) => {
4043
const {
@@ -85,7 +88,8 @@ export const VirtualTableBody = (props: VirtualTableBodyProps) => {
8588
[rowHeight, rows, renderRowSubComponent, alwaysShowSubComponent, subComponentsHeight]
8689
),
8790
overscan,
88-
measureElement
91+
measureElement,
92+
indexAttribute: 'data-virtual-row-index'
8993
});
9094
scrollToRef.current = {
9195
...scrollToRef.current,
@@ -161,7 +165,10 @@ export const VirtualTableBody = (props: VirtualTableBodyProps) => {
161165
lastNonEmptyRow.current = row;
162166
}
163167
prepareRow(row);
164-
const rowProps = row.getRowProps({ 'aria-rowindex': virtualRow.index });
168+
const rowProps = row.getRowProps({
169+
'aria-rowindex': virtualRow.index + 1,
170+
'data-virtual-row-index': virtualRow.index
171+
});
165172
const isNavigatedCell = markNavigatedRow(row);
166173
const RowSubComponent = typeof renderRowSubComponent === 'function' ? renderRowSubComponent(row) : undefined;
167174

@@ -182,21 +189,19 @@ export const VirtualTableBody = (props: VirtualTableBodyProps) => {
182189
) {
183190
updatedHeight += subComponentsHeight?.[virtualRow.index]?.subComponentHeight ?? 0;
184191
}
192+
185193
return (
186194
// eslint-disable-next-line react/jsx-key
187195
<div
188196
{...rowProps}
197+
ref={rowVirtualizer.measureElement}
189198
style={{
190199
...(rowProps.style ?? {}),
191200
transform: `translateY(${virtualRow.start}px)`,
192201
position: 'absolute',
193202
boxSizing: 'border-box',
194203
height: `${updatedHeight}px`
195204
}}
196-
ref={(node) => {
197-
virtualRow.measureElement(node);
198-
}}
199-
aria-rowindex={rowProps['aria-rowindex'] + 1}
200205
>
201206
{RowSubComponent && (row.isExpanded || alwaysShowSubComponent) && (
202207
<SubComponent
@@ -217,9 +222,9 @@ export const VirtualTableBody = (props: VirtualTableBodyProps) => {
217222
const directionStyles = isRtl
218223
? {
219224
transform: `translateX(-${virtualColumn.start}px)`,
220-
right: 0
225+
insertInlineStart: 0
221226
}
222-
: { transform: `translateX(${virtualColumn.start}px)`, left: 0 };
227+
: { transform: `translateX(${virtualColumn.start}px)`, insertInlineStart: 0 };
223228
if (!cell) {
224229
return null;
225230
}

0 commit comments

Comments
 (0)