Skip to content

Commit 8e657a4

Browse files
authored
feat: add the ability to pass function in estimatedRowHeight to determine the initial height of rows (#241)
1 parent 85669ef commit 8e657a4

File tree

6 files changed

+36
-9
lines changed

6 files changed

+36
-9
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## NEXT VERSION
44

5+
- feat: add the ability to pass function in `estimatedRowHeight` to determine the initial height of rows
6+
57
## v1.11.3 (2020-08-24)
68

79
- fix: remove propTypes for Column.key

src/BaseTable.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
renderElement,
2020
normalizeColumns,
2121
getScrollbarSize as defaultGetScrollbarSize,
22+
getEstimatedTotalRowsHeight,
2223
isObjectEqual,
2324
callOrReturn,
2425
hasChildren,
@@ -120,6 +121,7 @@ class BaseTable extends React.PureComponent {
120121
this._mainRowHeightMap = {};
121122
this._leftRowHeightMap = {};
122123
this._rightRowHeightMap = {};
124+
this._getEstimatedTotalRowsHeight = memoize(getEstimatedTotalRowsHeight);
123125
this._getRowHeight = this._getRowHeight.bind(this);
124126
this._updateRowHeights = debounce(() => {
125127
this._isResetting = true;
@@ -185,7 +187,9 @@ class BaseTable extends React.PureComponent {
185187
const { rowHeight, estimatedRowHeight } = this.props;
186188

187189
if (estimatedRowHeight) {
188-
return this.table ? this.table.getTotalRowsHeight() : this._data.length * estimatedRowHeight;
190+
return this.table
191+
? this.table.getTotalRowsHeight()
192+
: this._getEstimatedTotalRowsHeight(this._data, estimatedRowHeight);
189193
}
190194
return this._data.length * rowHeight;
191195
}
@@ -716,7 +720,7 @@ class BaseTable extends React.PureComponent {
716720
[`${classPrefix}--has-frozen-rows`]: frozenData.length > 0,
717721
[`${classPrefix}--has-frozen-columns`]: this.columnManager.hasFrozenColumns(),
718722
[`${classPrefix}--disabled`]: disabled,
719-
[`${classPrefix}--dynamic`]: estimatedRowHeight > 0,
723+
[`${classPrefix}--dynamic`]: !!estimatedRowHeight,
720724
});
721725
return (
722726
<div ref={this._setContainerRef} className={cls} style={containerStyle}>
@@ -785,7 +789,10 @@ class BaseTable extends React.PureComponent {
785789
// for dynamic row height
786790
_getRowHeight(rowIndex) {
787791
const { estimatedRowHeight, rowKey } = this.props;
788-
return this._rowHeightMap[this._data[rowIndex][rowKey]] || estimatedRowHeight;
792+
return (
793+
this._rowHeightMap[this._data[rowIndex][rowKey]] ||
794+
callOrReturn(estimatedRowHeight, { rowData: this._data[rowIndex], rowIndex })
795+
);
789796
}
790797

791798
_getIsResetting() {
@@ -1103,8 +1110,9 @@ BaseTable.propTypes = {
11031110
rowHeight: PropTypes.number,
11041111
/**
11051112
* Estimated row height, the real height will be measure dynamically according to the content
1113+
* The callback is of the shape of `({ rowData, rowIndex }) => number`
11061114
*/
1107-
estimatedRowHeight: PropTypes.number,
1115+
estimatedRowHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),
11081116
/**
11091117
* The height of the table header, set to 0 to hide the header, could be an array to render multi headers.
11101118
*/

src/GridTable.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { FixedSizeGrid, VariableSizeGrid } from 'react-window';
55
import memoize from 'memoize-one';
66

77
import Header from './TableHeader';
8+
import { getEstimatedTotalRowsHeight } from './utils';
89

910
/**
1011
* A wrapper of the Grid for internal only
@@ -23,6 +24,7 @@ class GridTable extends React.PureComponent {
2324
if (!this.props.estimatedRowHeight) return;
2425
this.bodyRef && this.bodyRef.resetAfterColumnIndex(0, false);
2526
});
27+
this._getEstimatedTotalRowsHeight = memoize(getEstimatedTotalRowsHeight);
2628

2729
this.renderRow = this.renderRow.bind(this);
2830
}
@@ -59,7 +61,9 @@ class GridTable extends React.PureComponent {
5961
const { data, rowHeight, estimatedRowHeight } = this.props;
6062

6163
if (estimatedRowHeight) {
62-
return (this.innerRef && this.innerRef.clientHeight) || data.length * estimatedRowHeight;
64+
return (
65+
(this.innerRef && this.innerRef.clientHeight) || this._getEstimatedTotalRowsHeight(data, estimatedRowHeight)
66+
);
6367
}
6468
return data.length * rowHeight;
6569
}
@@ -114,7 +118,7 @@ class GridTable extends React.PureComponent {
114118
width={width}
115119
height={Math.max(height - headerHeight - frozenRowsHeight, 0)}
116120
rowHeight={estimatedRowHeight ? getRowHeight : rowHeight}
117-
estimatedRowHeight={estimatedRowHeight}
121+
estimatedRowHeight={typeof estimatedRowHeight === 'function' ? undefined : estimatedRowHeight}
118122
rowCount={data.length}
119123
overscanRowCount={overscanRowCount}
120124
columnWidth={estimatedRowHeight ? this._getBodyWidth : bodyWidth}
@@ -198,7 +202,7 @@ GridTable.propTypes = {
198202
headerWidth: PropTypes.number.isRequired,
199203
bodyWidth: PropTypes.number.isRequired,
200204
rowHeight: PropTypes.number.isRequired,
201-
estimatedRowHeight: PropTypes.number,
205+
estimatedRowHeight: PropTypes.oneOfType([PropTypes.func, PropTypes.number]),
202206
getRowHeight: PropTypes.func,
203207
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
204208
data: PropTypes.array.isRequired,

src/TableRow.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ TableRow.propTypes = {
183183
rowRenderer: PropTypes.oneOfType([PropTypes.func, PropTypes.element]),
184184
cellRenderer: PropTypes.func,
185185
expandIconRenderer: PropTypes.func,
186-
estimatedRowHeight: PropTypes.number,
186+
estimatedRowHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),
187187
getIsResetting: PropTypes.func,
188188
onRowHover: PropTypes.func,
189189
onRowExpand: PropTypes.func,

src/utils.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,3 +251,9 @@ export function removeClassName(el, className) {
251251
el.className = el.className.replace(new RegExp(`(?:^|\\s)${className}(?!\\S)`, 'g'), '');
252252
}
253253
}
254+
255+
export function getEstimatedTotalRowsHeight(data, estimatedRowHeight) {
256+
return typeof estimatedRowHeight === 'function'
257+
? data.reduce((height, rowData, rowIndex) => height + estimatedRowHeight({ rowData, rowIndex }), 0)
258+
: data.length * estimatedRowHeight;
259+
}

types/index.d.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,15 @@ declare module 'react-base-table' {
208208
rowHeight?: number;
209209
/**
210210
* Estimated row height, the real height will be measure dynamically according to the content
211+
* The callback is of the shape of `({ rowData, rowIndex }) => number`
211212
*/
212-
estimatedRowHeight?: number;
213+
estimatedRowHeight?: CallOrReturn<
214+
number,
215+
{
216+
rowData: T;
217+
rowIndex: number;
218+
}
219+
>;
213220
/**
214221
* The height of the table header, set to 0 to hide the header, could be an array to render multi headers.
215222
*/

0 commit comments

Comments
 (0)