Skip to content

migrate to react-window #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
## NEXT VERSION

- chore: stop relying on `onScrollbarPresenceChange`
- feat: replace `react-virtualized` with `react-window`
- feat: add scroll direction to `onScroll`
- feat: add `align` to `scrollToRow`

# v1.1.1 (2019-04-27)

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
"memoize-one": "^5.0.0",
"prop-types": "^15.6.0",
"react-draggable": "^3.0.5",
"react-virtualized": "^9.18.5"
"react-virtualized-auto-sizer": "^1.0.2",
"react-window": "^1.8.1"
},
"peerDependencies": {
"react": "^16.0.0",
Expand Down
2 changes: 1 addition & 1 deletion src/AutoResizer.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import AutoSizer from 'react-virtualized/dist/commonjs/AutoSizer';
import AutoSizer from 'react-virtualized-auto-sizer';

/**
* Decorator component that automatically adjusts the width and height of a single child
Expand Down
36 changes: 27 additions & 9 deletions src/BaseTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,15 +176,26 @@ class BaseTable extends React.PureComponent {
}

/**
* Ensure row is visible.
* This method can be used to safely scroll back to a row that a user has scrolled away from even if it was previously scrolled to.
*
* @param {number} rowIndex
* Scroll to the specified row.
* By default, the table will scroll as little as possible to ensure the row is visible.
* You can control the alignment of the row though by specifying an align property. Acceptable values are:
*
* - `auto` (default) - Scroll as little as possible to ensure the row is visible.
* (If the row is already visible, it won't scroll at all.)
* - `smart` - If the row is already visible, don't scroll at all. If it is less than one viewport away,
* scroll as little as possible so that it becomes visible.
* If it is more than one viewport away, scroll so that it is centered within the grid.
* - `center` - Center align the row within the table.
* - `end` - Align the row to the bottom, right hand side of the table.
* - `start` - Align the row to the top, left hand of the table.

* @param {number} rowIndex
* @param {string} align
*/
scrollToRow(rowIndex = 0) {
this.table && this.table.scrollToRow(rowIndex);
this.leftTable && this.leftTable.scrollToRow(rowIndex);
this.rightTable && this.rightTable.scrollToRow(rowIndex);
scrollToRow(rowIndex = 0, align = 'auto') {
this.table && this.table.scrollToRow(rowIndex, align);
this.leftTable && this.leftTable.scrollToRow(rowIndex, align);
this.rightTable && this.rightTable.scrollToRow(rowIndex, align);
}

/**
Expand Down Expand Up @@ -1044,7 +1055,14 @@ BaseTable.propTypes = {
overscanRowCount: PropTypes.number,
/**
* A callback function when scrolling the table
* The handler is of the shape of `({ scrollLeft, scrollTop }) => *`
* The handler is of the shape of `({ scrollLeft, scrollTop, horizontalScrollDirection, verticalScrollDirection, scrollUpdateWasRequested }) => *`
*
* `scrollLeft` and `scrollTop` are numbers.
*
* `horizontalDirection` and `verticalDirection` are either `forward` or `backward`.
*
* `scrollUpdateWasRequested` is a boolean. This value is true if the scroll was caused by `scrollTo*`,
* and false if it was the result of a user interaction in the browser.
*/
onScroll: PropTypes.func,
/**
Expand Down
57 changes: 27 additions & 30 deletions src/GridTable.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import React from 'react';
import PropTypes from 'prop-types';
import cn from 'classnames';
import Grid from 'react-virtualized/dist/commonjs/Grid';
import { FixedSizeGrid as Grid } from 'react-window';

import Header from './TableHeader';
import cellRangeRenderer from './cellRangeRenderer';

/**
* A wrapper of the Grid for internal only
Expand All @@ -15,10 +14,10 @@ class GridTable extends React.PureComponent {

this._setHeaderRef = this._setHeaderRef.bind(this);
this._setBodyRef = this._setBodyRef.bind(this);
this._handleSectionRendered = this._handleSectionRendered.bind(this);
this._itemKey = this._itemKey.bind(this);
this._handleItemsRendered = this._handleItemsRendered.bind(this);

this.renderRow = this.renderRow.bind(this);
this.renderCellRange = this.renderCellRange.bind(this);
}

forceUpdateTable() {
Expand All @@ -28,24 +27,20 @@ class GridTable extends React.PureComponent {

scrollToPosition(args) {
this.headerRef && this.headerRef.scrollTo(args.scrollLeft);
this.bodyRef && this.bodyRef.scrollToPosition(args);
this.bodyRef && this.bodyRef.scrollTo(args);
}

scrollToTop(scrollTop) {
this.bodyRef && this.bodyRef.scrollToPosition({ scrollTop });
this.bodyRef && this.bodyRef.scrollTo({ scrollTop });
}

scrollToLeft(scrollLeft) {
this.headerRef && this.headerRef.scrollTo(scrollLeft);
this.bodyRef && this.bodyRef.scrollToPosition({ scrollLeft });
}

scrollToRow(rowIndex = 0) {
this.bodyRef &&
this.bodyRef.scrollToCell({
rowIndex,
columnIndex: 0,
});
scrollToRow(rowIndex = 0, align = 'auto') {
this.bodyRef && this.bodyRef.scrollToItem({ rowIndex, columnIndex: 0, align });
}

renderRow(args) {
Expand All @@ -54,12 +49,6 @@ class GridTable extends React.PureComponent {
return rowRenderer({ ...args, columns, rowData });
}

renderCellRange(args) {
const { useIsScrolling } = this.props;
const isScrolling = useIsScrolling ? args.isScrolling : undefined;
return cellRangeRenderer({ ...args, useIsScrolling, isScrolling });
}

render() {
const {
containerStyle,
Expand All @@ -75,6 +64,7 @@ class GridTable extends React.PureComponent {
useIsScrolling,
onScroll,
hoveredRowKey,
overscanRowCount,
// omit from rest
style,
onScrollbarPresenceChange,
Expand All @@ -92,19 +82,21 @@ class GridTable extends React.PureComponent {
className={`${classPrefix}__body`}
ref={this._setBodyRef}
data={data}
itemKey={this._itemKey}
frozenData={frozenData}
width={width}
height={Math.max(height - headerHeight - frozenRowsHeight, 0)}
rowHeight={rowHeight}
rowCount={data.length}
overscanRowsCount={overscanRowCount}
columnWidth={bodyWidth}
columnCount={1}
isScrollingOptOut={!useIsScrolling}
cellRenderer={this.renderRow}
cellRangeRenderer={this.renderCellRange}
overscanColumnsCount={0}
useIsScrolling={useIsScrolling}
hoveredRowKey={hoveredRowKey}
onScroll={onScroll}
onSectionRendered={this._handleSectionRendered}
onItemsRendered={this._handleItemsRendered}
children={this.renderRow}
/>
{headerHeight + frozenRowsHeight > 0 && (
// put header after body and reverse the display order via css
Expand Down Expand Up @@ -137,6 +129,11 @@ class GridTable extends React.PureComponent {
this.bodyRef = ref;
}

_itemKey({ rowIndex }) {
const { data, rowKey } = this.props;
return data[rowIndex][rowKey];
}

_getHeaderHeight() {
const { headerHeight } = this.props;
if (Array.isArray(headerHeight)) {
Expand All @@ -145,14 +142,12 @@ class GridTable extends React.PureComponent {
return headerHeight;
}

_handleSectionRendered({ rowOverscanStartIndex, rowOverscanStopIndex, rowStartIndex, rowStopIndex }) {
const { onRowsRendered } = this.props;

onRowsRendered({
overscanStartIndex: rowOverscanStartIndex,
overscanStopIndex: rowOverscanStopIndex,
startIndex: rowStartIndex,
stopIndex: rowStopIndex,
_handleItemsRendered({ overscanRowStartIndex, overscanRowStopIndex, visibleRowStartIndex, visibleRowStopIndex }) {
this.props.onRowsRendered({
overscanStartIndex: overscanRowStartIndex,
overscanStopIndex: overscanRowStopIndex,
startIndex: visibleRowStartIndex,
stopIndex: visibleRowStopIndex,
});
}
}
Expand All @@ -169,8 +164,10 @@ GridTable.propTypes = {
rowHeight: PropTypes.number.isRequired,
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
data: PropTypes.arrayOf(PropTypes.object).isRequired,
rowKey: PropTypes.string.isRequired,
frozenData: PropTypes.arrayOf(PropTypes.object),
useIsScrolling: PropTypes.bool,
overscanRowCount: PropTypes.number,
hoveredRowKey: PropTypes.string,
style: PropTypes.object,
onScrollbarPresenceChange: PropTypes.func,
Expand Down
Loading