Skip to content

Commit 53c0db4

Browse files
feat(AnalyticalTable): add subComponentsBehavior prop (#4986)
This PR adds the `subComponentsBehavior` prop which accepts the `AnalyticalTableSelectionBehavior` enum. It enables controlling how subcomponents should be rendered and if they should be considered when calculating the initial table body height. `alwaysShowSubComponent` has been deprecated in favor of `subComponentsBehavior`. Fixes #3862 --------- Co-authored-by: Marcus Notheis <[email protected]>
1 parent 59639a7 commit 53c0db4

File tree

7 files changed

+193
-37
lines changed

7 files changed

+193
-37
lines changed

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

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { cssVarToRgb, cypressPassThroughTestsFactory } from '@/cypress/support/utils';
12
import { ThemingParameters } from '@ui5/webcomponents-react-base';
23
import { useCallback, useEffect, useRef, useState } from 'react';
34
import type { AnalyticalTablePropTypes } from '../..';
@@ -6,13 +7,13 @@ import {
67
AnalyticalTableHooks,
78
AnalyticalTableScaleWidthMode,
89
AnalyticalTableSelectionBehavior,
10+
AnalyticalTableSubComponentsBehavior,
911
Button,
1012
Input
1113
} from '../..';
1214
import { AnalyticalTableSelectionMode, AnalyticalTableVisibleRowCountMode, ValueState } from '../../enums/index.js';
1315
import { useManualRowSelect } from './pluginHooks/useManualRowSelect';
1416
import { useRowDisableSelection } from './pluginHooks/useRowDisableSelection';
15-
import { cssVarToRgb, cypressPassThroughTestsFactory } from '@/cypress/support/utils';
1617

1718
const generateMoreData = (count) => {
1819
return new Array(count).fill('').map((item, index) => ({
@@ -1476,6 +1477,13 @@ describe('AnalyticalTable', () => {
14761477
});
14771478

14781479
it('render subcomponents', () => {
1480+
const renderRowSubComponentLarge = (row) => {
1481+
return (
1482+
<div title="subcomponent" style={{ height: '200px', width: '100%', display: 'flex', alignItems: 'end' }}>
1483+
{`SubComponent ${row.index}`}
1484+
</div>
1485+
);
1486+
};
14791487
const renderRowSubComponent = () => {
14801488
return <div title="subcomponent">SubComponent</div>;
14811489
};
@@ -1519,7 +1527,7 @@ describe('AnalyticalTable', () => {
15191527
data={data}
15201528
columns={columns}
15211529
renderRowSubComponent={renderRowSubComponent}
1522-
alwaysShowSubComponent
1530+
subComponentsBehavior={AnalyticalTableSubComponentsBehavior.Visible}
15231531
/>
15241532
);
15251533
cy.findAllByText('SubComponent').should('be.visible').should('have.length', 4);
@@ -1531,12 +1539,40 @@ describe('AnalyticalTable', () => {
15311539
data={data}
15321540
columns={columns}
15331541
renderRowSubComponent={onlyFirstRowWithSubcomponent}
1534-
alwaysShowSubComponent
1542+
subComponentsBehavior={AnalyticalTableSubComponentsBehavior.Visible}
15351543
/>
15361544
);
15371545
cy.findByText('SingleSubComponent').should('be.visible').should('have.length', 1);
15381546
cy.findByTitle('Expand Node').should('not.exist');
15391547
cy.findByTitle('Collapse Node').should('not.exist');
1548+
1549+
cy.mount(
1550+
<AnalyticalTable
1551+
data={data}
1552+
columns={columns}
1553+
renderRowSubComponent={renderRowSubComponentLarge}
1554+
visibleRows={3}
1555+
subComponentsBehavior={AnalyticalTableSubComponentsBehavior.Visible}
1556+
/>
1557+
);
1558+
1559+
cy.findByText('SubComponent 1').should('exist').and('not.be.visible');
1560+
cy.findByTitle('Expand Node').should('not.exist');
1561+
cy.findByTitle('Collapse Node').should('not.exist');
1562+
1563+
cy.mount(
1564+
<AnalyticalTable
1565+
data={data}
1566+
columns={columns}
1567+
renderRowSubComponent={renderRowSubComponentLarge}
1568+
visibleRows={3}
1569+
subComponentsBehavior={AnalyticalTableSubComponentsBehavior.IncludeHeight}
1570+
/>
1571+
);
1572+
cy.findByText('SubComponent 1').should('be.visible');
1573+
cy.findByText('SubComponent 2').should('be.visible');
1574+
cy.findByTitle('Expand Node').should('not.exist');
1575+
cy.findByTitle('Collapse Node').should('not.exist');
15401576
});
15411577

15421578
it('pop-in columns', () => {
@@ -2300,7 +2336,7 @@ describe('AnalyticalTable', () => {
23002336
<AnalyticalTable
23012337
data={generateMoreData(50)}
23022338
columns={columns.slice(0, 2)}
2303-
alwaysShowSubComponent
2339+
subComponentsBehavior={AnalyticalTableSubComponentsBehavior.Visible}
23042340
renderRowSubComponent={renderSubComp}
23052341
/>
23062342
);
@@ -2344,7 +2380,7 @@ describe('AnalyticalTable', () => {
23442380
<AnalyticalTable
23452381
data={generateMoreData(50)}
23462382
columns={columns.slice(0, 2)}
2347-
alwaysShowSubComponent
2383+
subComponentsBehavior={AnalyticalTableSubComponentsBehavior.Visible}
23482384
renderRowSubComponent={renderSubComp2}
23492385
/>
23502386
);

packages/main/src/components/AnalyticalTable/AnalyticalTable.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,14 +276,14 @@ const InfiniteScrollTable = (props) => {
276276
## AnalyticalTable with subcomponents
277277

278278
Adding custom subcomponents below table rows can be achieved by setting the `renderRowSubComponent` prop.
279-
The prop expects a function with an optional parameter containing the `row` instance, there you can control which row should display subcomponents. If you want to display the subcomponent at the bottom of the row without an expandable container, you can set the `alwaysShowSubComponent` prop to `true`.
279+
The prop expects a function with an optional parameter containing the `row` instance, there you can control which row should display subcomponents. If you want to display the subcomponent at the bottom of the row without an expandable container, you can set `subComponentsBehavior` prop to `"Visible"` or to `"IncludeHeight"`. "Visible" simply adds the subcomponent to the row without including its height in the initial calculation of the table body, whereas "IncludeHeight" does.
280280

281281
### Notes
282282

283283
- When `renderRowSubComponent` is set, `grouping` is disabled.
284284
- When rendering active elements inside the subcomponent, make sure to add the `data-subcomponent-active-element' attribute, otherwise focus behavior won't be consistent.
285285

286-
<ControlsWithNote of={ComponentStories.Subcomponents} include={['alwaysShowSubComponent', 'renderRowSubComponent']} />
286+
<ControlsWithNote of={ComponentStories.Subcomponents} include={['renderRowSubComponent', 'subComponentsBehavior']} />
287287

288288
<Canvas sourceState="none" of={ComponentStories.Subcomponents} />
289289

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { useVirtualizer } from '@tanstack/react-virtual';
22
import { clsx } from 'clsx';
33
import type { MutableRefObject, ReactNode } from 'react';
44
import React, { useCallback, useMemo, useRef } from 'react';
5+
import type { AnalyticalTablePropTypes } from '../index.js';
56
import type { ScrollToRefType } from '../interfaces.js';
67
import { getSubRowsByString } from '../util/index.js';
78
import { EmptyRow } from './EmptyRow.js';
@@ -23,13 +24,14 @@ interface VirtualTableBodyProps {
2324
renderRowSubComponent: (row?: Record<string, unknown>) => ReactNode;
2425
popInRowHeight: number;
2526
isRtl: boolean;
26-
markNavigatedRow?: (row?: Record<string, unknown>) => boolean;
27+
markNavigatedRow?: AnalyticalTablePropTypes['markNavigatedRow'];
2728
alwaysShowSubComponent: boolean;
2829
dispatch?: (e: { type: string; payload?: Record<string, unknown> }) => void;
2930
subComponentsHeight?: Record<string, { rowId: string; subComponentHeight?: number }>;
3031
columnVirtualizer: Record<string, any>;
3132
manualGroupBy?: boolean;
3233
subRowsKey: string;
34+
scrollContainerRef?: MutableRefObject<HTMLDivElement>;
3335
}
3436

3537
const measureElement = (el) => el.offsetHeight;
@@ -57,7 +59,8 @@ export const VirtualTableBody = (props: VirtualTableBodyProps) => {
5759
subComponentsHeight,
5860
columnVirtualizer,
5961
manualGroupBy,
60-
subRowsKey
62+
subRowsKey,
63+
scrollContainerRef
6164
} = props;
6265

6366
const itemCount = Math.max(minRows, rows.length);
@@ -102,6 +105,7 @@ export const VirtualTableBody = (props: VirtualTableBodyProps) => {
102105
);
103106
return (
104107
<div
108+
ref={scrollContainerRef}
105109
data-component-name="AnalyticalTableBodyScrollableContainer"
106110
style={{
107111
position: 'relative',

0 commit comments

Comments
 (0)