feat: add support for dynamic row height#170
Conversation
|
Thanks for your contribution, that's a great feature, I have some questions before I take some time for a detailed review
|
|
@nihgwu Hi, yes it does currently work w/ frozen columns as well as frozen rows. LeftGrid, RightGrid, and MainGrid each call |
|
@nihgwu As far as using |
| const cellProps = { isScrolling, cellData, columns, column, columnIndex, rowData, rowIndex, container: this }; | ||
| const cell = renderElement(cellRenderer || <TableCell className={this._prefixClass('row-cell-text')} />, cellProps); | ||
| const cellClasses = cn(this._prefixClass('row-cell-text'), { | ||
| [this._prefixClass('row-cell-text-dynamic')]: this.props.useDynamicRowHeight, |
There was a problem hiding this comment.
I think the dynamic should be promoted to the row(row--dynamic) and use :not(.row--dynamic) { .cell-text{} }
There was a problem hiding this comment.
perhaps we should promote even further to the top level like table--dynamic, as all the rows would have the same row--dynamic className
There was a problem hiding this comment.
I was thinking maybe only applying row-cell-text when not in dynamic mode. None of those properties have any affect when content is dynamically sized, so always adding them and overriding is un-necessary work.
| ); | ||
| } | ||
|
|
||
| setRowHeight = (index, size) => { |
There was a problem hiding this comment.
we don't use arrow functions in a class component
There was a problem hiding this comment.
Have you considered about expansion? The indices would change on expand/collapse
There was a problem hiding this comment.
Expansion seems to have fine performance for me locally. I can update this to not use arrow functions.
There was a problem hiding this comment.
I think i see what you were alluding to w/ expansion. It seems its not entirely correct. I'll dig into fixing it.
There was a problem hiding this comment.
I think you can use rowKey as the key instead of index, as you can have totally different data with the same index
|
|
||
| if (rowHeightMap.hasOwnProperty(index)) { | ||
| if (size > rowHeightMap[index]) { | ||
| rowHeightMap[index] = size; |
There was a problem hiding this comment.
If you are using index as the key, why not use an array directly?
also you should use {...map, [index]: size} to mutate the ref
and if there is no need to re-render, you don't need to always setState at the bottom
There was a problem hiding this comment.
I didn't use an array bc of how rowIndex is negative for frozen rows. It seemed simpler to pass props.rowIndex directly through instead of adding logic to figure out original index.
There was a problem hiding this comment.
yes, I totally forget that 👍
|
Yes in the next major version I will use hooks, but for this version we should try to avoid breaking changes |
|
For the context, I remember there is a compatible package there? |
|
Perhaps. I haven't used any but I can check to see if one exists. |
|
I haven't check if we do need the new context, but here is the polyfill for it https://github.com/jamiebuilds/create-react-context |
| ExpandIcon: PropTypes.func, | ||
| SortIndicator: PropTypes.func, | ||
| }), | ||
| useDynamicRowHeight: PropTypes.bool, |
There was a problem hiding this comment.
maybe we could use estimatedRowHeight for initial height and scrollToRow
There was a problem hiding this comment.
if this value is presented, we use VariableSizeGrid and ignore rowHeight
| rowRenderer={this.renderRow} | ||
| onScroll={this._handleScroll} | ||
| onRowsRendered={this._handleRowsRendered} | ||
| useDynamicRowHeight={useDynamicRowHeight} |
There was a problem hiding this comment.
I think we can use rowHeight: func|number here, then we don't need to pass so many extra props
There was a problem hiding this comment.
Do you think rowHeight should become optional then? If user provides number or func, we use that otherwise it's internally calculated using the TableRow.getBoundingClientRect().height that I added?
There was a problem hiding this comment.
I think that's not the same case, for the BaseTable, the rowHeight could be optional as there is a default value, so actually we can remove the isRequired in the propTypes definition without breaking anything, and if we provide estimatedRowHeight we will ignore rowHeight and use estimatedRowHeight instead
for the GridTable, we use rowHeight: number as before, but rowHeight: func in dynamic mode, like rowHeight = index => rowHeightMap[index], in this way we don't need to change the props interface at all
There was a problem hiding this comment.
Ok, I think i'm following. I'll push an update and see if we're on same page.
|
For get to mention that if you have tested with the infinite loading feature, I think we can use the innerRef to get the totalRowHeight instead of calculate from the count and rowHeight https://github.com/Autodesk/react-base-table/blob/master/src/BaseTable.js#L150, in that way I think we can make that feature works |
|
@jamesonhill I just pushed another commit, now you can reset cache without losing performance on resizing, it looks much better now |
|
I haven't been able to track down what's causing it yet, but i'm seeing a little bit of "weird-ness" the first time I hover over a row (using dynamic heights). It gets smaller while hovering, then goes back to the correct size |
|
@jamesonhill I've noticed that problem too, will inspect it |
|
@jamesonhill I've tracked down the issue, but just don't know why ;(, when you hover on a row the first time, the |
|
@nihgwu yea, that is odd. I'm debugging it and it even looks like they are the same unless i'm missing something. |
|
Oh, nevermind. It looks like first render is using the estimatedRowHeight values, which makes sense. |
|
@jamesonhill the object value is the same but the reference is different before/after reset cache |
|
@jamesonhill I've fixed the issue, and I think it's ready to be merged, please help to review the code I changed, thanks |
|
@nihgwu it looks good to me. I've done some local testing and don't see the hover issue anymore. Scrolling w/ dynamic row heights is quite fast too! I think it's ready to merge. |
|
@jamesonhill Cool, let's land it, thank you so much 🎉 |
|
Awesome, thanks for your assistance & guidance. This should only require a minor version bump to the npm package? |
|
sure, I'm experimenting with List instead of Grid, if it's a easy switch I want to include it, or I'll release a new version soon |
|
v1.10.0 is released, I've make List work but it requires api change on |
|
@jamesonhill I noticed an issue regarding the out sync of measurement in productionhttps://autodesk.github.io/react-base-table/examples/dynamic-row-heights, I guess it's caused by the fact that it's much faster in production that debounce of |
|
hmm, I'm actually seeing it locally but not in that production example. |
|
LOL, that's interesting, I'm trying to fix it now |
This adds a new prop
estimatedRowHeight, which updates the Grid component to useVariableSizeGridfromreact-windowinstead ofFixedSizeGrid. WhenestimatedRowHeightis provided,rowHeightis ignored and content is dynamically sized.estimatedRowHeightis used as the default height while measuring the content.