Skip to content

Commit 74f8309

Browse files
committed
add more JSDoc comments, enhance story, fix ininite scroll threshold
1 parent 350112e commit 74f8309

File tree

3 files changed

+134
-79
lines changed

3 files changed

+134
-79
lines changed

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

Lines changed: 115 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Meta, Story, Canvas, ArgsTable } from '@storybook/addon-docs/blocks';
1+
import { ArgsTable, Canvas, Meta, Story } from '@storybook/addon-docs/blocks';
22
import { AnalyticalTable } from '@ui5/webcomponents-react/lib/AnalyticalTable';
33
import { createSelectArgTypes } from '../../../../../shared/stories/createSelectArgTypes';
44
import { TableScaleWidthMode } from '@ui5/webcomponents-react/lib/TableScaleWidthMode';
@@ -15,6 +15,7 @@ import { TextAlign } from '@ui5/webcomponents-react/lib/TextAlign';
1515
import { DefaultLoadingComponent } from './defaults/LoadingComponent';
1616
import { DefaultNoDataComponent } from './defaults/NoDataComponent';
1717
import { DocsCommonProps } from '@shared/stories/DocsCommonProps';
18+
import { useEffect, useRef, useState } from 'react';
1819

1920
<Meta
2021
title="Components / AnalyticalTable"
@@ -125,42 +126,7 @@ import { DocsCommonProps } from '@shared/stories/DocsCommonProps';
125126
<DocsHeader />
126127

127128
<Canvas>
128-
<Story name="Default">
129-
{(args) => (
130-
<div style={{ display: 'flex', flexDirection: 'column' }}>
131-
<AnalyticalTable
132-
{...args}
133-
title={args.title}
134-
data={args.data}
135-
columns={args.columns}
136-
loading={args.loading}
137-
alternateRowColor={args.alternateRowColor}
138-
sortable={args.sortable}
139-
filterable={args.filterable}
140-
visibleRows={args.visibleRows}
141-
minRows={args.minRows}
142-
groupable={args.groupable}
143-
selectionMode={args.selectionMode}
144-
scaleWidthMode={args.scaleWidthMode}
145-
onRowSelected={args.onRowSelected}
146-
onSort={args.onSort}
147-
onGroup={args.onGroup}
148-
onRowExpandChange={args.onRowExpandChange}
149-
groupBy={args.groupBy}
150-
rowHeight={args.rowHeight}
151-
selectedRowIds={args.selectedRowIds}
152-
onColumnsReordered={args.onColumnsReordered}
153-
withRowHighlight={args.withRowHighlight}
154-
highlightField={args.highlightField}
155-
infiniteScroll={args.infiniteScroll}
156-
infiniteScrollThreshold={args.infiniteScrollThreshold}
157-
onLoadMore={args.onLoadMore}
158-
selectionBehavior={args.selectionBehavior}
159-
overscanCountHorizontal={args.overscanCountHorizontal}
160-
/>
161-
</div>
162-
)}
163-
</Story>
129+
<Story name="Default">{(args) => <AnalyticalTable {...args} />}</Story>
164130
</Canvas>
165131

166132
<ArgsTable story="." />
@@ -203,6 +169,13 @@ import { DocsCommonProps } from '@shared/stories/DocsCommonProps';
203169

204170
## Recipes
205171

172+
### How to select rows containing active elements?
173+
174+
By default, the `AnalyticalTable` will not select any rows after clicking on active elements inside a table cell like a `Button`, `Link`,
175+
etc. <br />
176+
In case you want to select the row anyways, you can "mark" the event to allow such a behaviour. <br />
177+
Example: `<Link onClick={(e) => {e.markerAllowTableRowSelection = true;}>My Link Text</Link>`
178+
206179
### How do I stop my table state from automatically resetting when my data changes?
207180

208181
By default, the `AnalyticalTable` will reset the sorters, filters, grouping, selected rows, etc. when the table data changes.
@@ -272,32 +245,115 @@ export const ResponsiveTable = () => {
272245
With the help of that effect, the table will now show either 2 columns on a mobile phone, 3 columns on a tablet device and all columns on Desktop devices.
273246
This even works if you resize the browser window!
274247

248+
<br />
249+
275250
# Stories
276251

252+
<br />
253+
277254
## Tree Table
278255

279256
<Canvas>
280-
<Story name="Tree Table" args={{ data: generateData(20, true) }}>
281-
{(args) => (
282-
<AnalyticalTable
283-
{...args}
284-
title={args.title}
285-
data={args.data}
286-
columns={args.columns}
287-
loading={args.loading}
288-
sortable={args.sortable}
289-
filterable={args.filterable}
290-
visibleRows={args.visibleRows}
291-
minRows={args.minRows}
292-
selectionMode={args.selectionMode}
293-
onRowSelected={args.onRowSelected}
294-
onSort={args.onSort}
295-
onRowExpandChange={args.onRowExpandChange}
296-
subRowsKey={args.subRowsKey}
297-
selectedRowIds={args.selectedRowIds}
298-
selectionBehavior={args.selectionBehavior}
299-
isTreeTable
300-
/>
301-
)}
257+
<Story name="Tree Table" args={{ data: generateData(20, true), isTreeTable: true }}>
258+
{(args) => <AnalyticalTable {...args} />}
259+
</Story>
260+
</Canvas>
261+
262+
The `data` structure of the tree table is as follows:
263+
264+
```js
265+
const data = {
266+
name: "Greg Miller",
267+
age: 35,
268+
friend: {
269+
name: "Rose Franco",
270+
age: 32,
271+
},
272+
status: "None",
273+
subRows: [
274+
{
275+
name: "Rick DeAngelo",
276+
age: 25,
277+
friend: {
278+
name: "Susanne Franco",
279+
age: 37,
280+
},
281+
status: "None",
282+
subRows: [...],
283+
},
284+
],
285+
...
286+
};
287+
```
288+
289+
In this example the default key for sub row detection is used (`subRows`), you can use any key you like by setting the `subRowsKey` prop.
290+
291+
<br />
292+
293+
## Infinite Scrolling
294+
295+
The table initially contains 50 rows, when the last 10 rows are reached the table will load more data.
296+
297+
<Canvas>
298+
<Story name="Infinite Scrolling">
299+
{(args) => {
300+
const [data, setData] = useState(args.data.slice(0, 50));
301+
const [loading, setLoading] = useState(false);
302+
const offset = useRef(50);
303+
const onLoadMore = () => {
304+
setLoading(true);
305+
};
306+
useEffect(() => {
307+
if (loading) {
308+
setTimeout(() => {
309+
setData((prev) => [...prev, ...args.data.slice(offset.current, offset.current + 50)]);
310+
setLoading(false);
311+
offset.current += 50;
312+
}, 2000);
313+
}
314+
}, [loading, args.data, offset.current]);
315+
return (
316+
<AnalyticalTable
317+
data={data}
318+
columns={args.columns}
319+
infiniteScroll={true}
320+
infiniteScrollThreshold={10}
321+
title="Scroll to load more data"
322+
onLoadMore={onLoadMore}
323+
loading={loading}
324+
/>
325+
);
326+
}}
302327
</Story>
303328
</Canvas>
329+
330+
```jsx
331+
const InfiniteScrollTable = (props) => {
332+
const [data, setData] = useState(props.data.slice(0, 50));
333+
const [loading, setLoading] = useState(false);
334+
const offset = useRef(50);
335+
const onLoadMore = () => {
336+
setLoading(true);
337+
};
338+
useEffect(() => {
339+
if (loading) {
340+
setTimeout(() => {
341+
setData((prev) => [...prev, ...props.data.slice(offset.current, offset.current + 50)]);
342+
setLoading(false);
343+
offset.current += 50;
344+
}, 2000);
345+
}
346+
}, [loading, props.data, offset.current]);
347+
return (
348+
<AnalyticalTable
349+
data={data}
350+
columns={props.columns}
351+
infiniteScroll={true}
352+
infiniteScrollThreshold={10}
353+
title="Scroll to load more data"
354+
onLoadMore={onLoadMore}
355+
loading={loading}
356+
/>
357+
);
358+
};
359+
```

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ export const VirtualTableBodyContainer = (props) => {
1313
onLoadMore,
1414
rows,
1515
internalRowHeight,
16-
handleExternalScroll
16+
handleExternalScroll,
17+
visibleRows
1718
} = props;
1819
const [isMounted, setIsMounted] = useState(false);
1920

@@ -35,8 +36,8 @@ export const VirtualTableBodyContainer = (props) => {
3536
const isScrollingDown = lastScrollTop.current < scrollOffset;
3637
if (isScrollingDown && infiniteScroll) {
3738
lastScrollTop.current = scrollOffset;
38-
const currentTopRow = Math.floor(scrollOffset / internalRowHeight);
39-
if (rows.length - currentTopRow < infiniteScrollThreshold) {
39+
const currentLastRow = Math.floor(scrollOffset / internalRowHeight) + visibleRows;
40+
if (rows.length - currentLastRow < infiniteScrollThreshold) {
4041
if (!firedInfiniteLoadEvents.current.has(rows.length)) {
4142
onLoadMore({
4243
detail: {

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

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export interface TableProps extends Omit<CommonProps, 'title'> {
7575
*/
7676
data: Record<any, any>[];
7777
/**
78-
* Component or text rendered in the title section of the `AnalyticalTable`.
78+
* Component or text rendered in the title section of the `AnalyticalTable`.<br />
7979
* __Note:__ If not set, it will be hidden.
8080
*/
8181
title?: ReactText | ReactNode;
@@ -90,12 +90,12 @@ export interface TableProps extends Omit<CommonProps, 'title'> {
9090
*/
9191
minRows?: number;
9292
/**
93-
* The number of rows visible without going into overflow.
93+
* The number of rows visible without going into overflow.<br />
9494
* __Note:__ If the data contains more entries than the `visibleRow` count, a vertical scrollbar is rendered and the table goes into overflow.
9595
*/
9696
visibleRows?: number;
9797
/**
98-
* Indicates whether a loading indicator should be shown.
98+
* Indicates whether a loading indicator should be shown.<br />
9999
* __Note:__ If the data array is not empty and loading is set to `true` a `Loader` will be displayed underneath the header, otherwise a loading placeholder will be shown.
100100
* You can use your own placeholder by passing it to the `LoadingComponent` prop.
101101
*/
@@ -144,17 +144,17 @@ export interface TableProps extends Omit<CommonProps, 'title'> {
144144
*/
145145
groupBy?: string[];
146146
/**
147-
* Defines the selection behavior of the table. <br />
148-
* __"Row":__ A selection column is rendered along with the normal columns. The whole row is selectable.
149-
* __"RowOnly":__ No selection column is rendered along with the normal columns. The whole row is selectable.
150-
* __"RowSelector":__ The row is only selectable by clicking on the corresponding field in the selection column.
147+
* Defines the selection behavior of the table.<br />
148+
* - __"Row":__ A selection column is rendered along with the normal columns. The whole row is selectable.
149+
* - __"RowOnly":__ No selection column is rendered along with the normal columns. The whole row is selectable.
150+
* - __"RowSelector":__ The row is only selectable by clicking on the corresponding field in the selection column.
151151
*/
152152
selectionBehavior?: TableSelectionBehavior;
153153
/**
154154
* Defines the `SelectionMode` of the table.<br />
155-
* __"None":__ The rows are not selectable.
156-
* __"SingleSelect":__ You can select only one row at once. Clicking on another row will unselect the previously selected row.
157-
* __"MultiSelect":__ You can select multiple rows.
155+
* - __"None":__ The rows are not selectable.
156+
* - __"SingleSelect":__ You can select only one row at once. Clicking on another row will unselect the previously selected row.
157+
* - __"MultiSelect":__ You can select multiple rows.
158158
*/
159159
selectionMode?: TableSelectionMode;
160160
/**
@@ -175,7 +175,8 @@ export interface TableProps extends Omit<CommonProps, 'title'> {
175175
*/
176176
infiniteScroll?: boolean;
177177
/**
178-
* Defines the infinite scroll threshold. When the threshold is reached, the `onLoadMore` event is fired.
178+
* The `infiniteScrollThreshold` defines at how many remaining rows the `onLoadMore` event should be fired.<br />
179+
* Example: Your initial dataset consists of 50 entries and you want to load more data when the user scrolled to the 40th row. Then you should set the `infiniteScrollThreshold` to 10.
179180
*/
180181
infiniteScrollThreshold?: number;
181182

@@ -246,13 +247,9 @@ export interface TableProps extends Omit<CommonProps, 'title'> {
246247
}
247248

248249
const useStyles = createComponentStyles(styles, { name: 'AnalyticalTable' });
249-
250250
/**
251-
* ### Usage Notes
252-
* By default, the `AnalyticalTable` will not select any rows after clicking on active elements like a `Button`, `Link`,
253-
* etc. <br />
254-
* In case you want to select the row anyways, you can "mark" the event to allow such a behaviour. <br />
255-
* Example: `<Link onClick={(e) => {e.markerAllowTableRowSelection = true;}>My Link Text</Link>`
251+
* The `AnalyticalTable` provides a set of convenient functions for responsive table design, including virtualization of rows and columns, infinite scrolling and customizable columns that will, unless otherwise defined, distribute the available space equally among themselves.
252+
* It also provides several possibilities for working with the data, including sorting, filtering, grouping and aggregation.
256253
*/
257254
const AnalyticalTable: FC<TableProps> = forwardRef((props: TableProps, ref: Ref<HTMLDivElement>) => {
258255
const {
@@ -587,6 +584,7 @@ const AnalyticalTable: FC<TableProps> = forwardRef((props: TableProps, ref: Ref<
587584
internalRowHeight={internalRowHeight}
588585
rows={rows}
589586
handleExternalScroll={handleBodyScroll}
587+
visibleRows={visibleRows}
590588
>
591589
<VirtualTableBody
592590
classes={classes}

0 commit comments

Comments
 (0)