{cellDeleter}
- {...props} />
+
+
+ rowIdx={rowIdx}
+ rowData={rowData}
+ column={column}
+ value={value}
+ isScrolling={isScrolling}
+ />
+
{cellControls}
{tooltip &&
{tooltip}}
diff --git a/packages/react-data-grid/src/ColumnMetrics.ts b/packages/react-data-grid/src/ColumnMetrics.ts
index 8beb010077..64f57ca1d7 100644
--- a/packages/react-data-grid/src/ColumnMetrics.ts
+++ b/packages/react-data-grid/src/ColumnMetrics.ts
@@ -1,6 +1,6 @@
export { sameColumn } from './ColumnComparer';
import { getSize, isFrozen } from './ColumnUtils';
-import getScrollbarSize from './getScrollbarSize';
+import { getScrollbarSize } from './utils';
import { isColumnsImmutable } from './common/utils';
import { Column, CalculatedColumn, ColumnList, ColumnMetrics } from './common/types';
@@ -57,7 +57,8 @@ export function recalculate
(metrics: Metrics): ColumnMetrics {
setColumnWidths(columns, metrics.totalWidth);
const width = getTotalColumnWidth(columns);
- const unallocatedWidth = metrics.totalWidth - width - getScrollbarSize();
+ const borderWidth = 2;
+ const unallocatedWidth = metrics.totalWidth - width - getScrollbarSize() - borderWidth;
// compute width for columns which doesn't specify width
setDefferedColumnWidths(columns, unallocatedWidth, metrics.minColumnWidth);
@@ -72,6 +73,7 @@ export function recalculate(metrics: Metrics): ColumnMetrics {
return {
width,
columns: calculatedColumns,
+ lastFrozenColumnIndex: frozenColumns.length - 1,
totalWidth: metrics.totalWidth,
totalColumnWidth: getTotalColumnWidth(columns),
minColumnWidth: metrics.minColumnWidth
diff --git a/packages/react-data-grid/src/Grid.tsx b/packages/react-data-grid/src/Grid.tsx
index e4bc05dc2c..d3718a6f8f 100644
--- a/packages/react-data-grid/src/Grid.tsx
+++ b/packages/react-data-grid/src/Grid.tsx
@@ -1,9 +1,8 @@
-import React from 'react';
+import React, { useRef, createElement, useEffect } from 'react';
import { isValidElementType } from 'react-is';
import Header from './Header';
import Viewport, { ScrollState } from './Viewport';
-import { isFrozen } from './ColumnUtils';
import { HeaderRowData, CellMetaData, RowSelection, InteractionMasksMetaData, SelectedRow } from './common/types';
import { DEFINE_SORT } from './common/enums';
import { DataGridProps, DataGridState } from './ReactDataGrid';
@@ -30,6 +29,9 @@ type SharedDataGridProps = Pick,
| 'onHeaderDrop'
| 'getSubRowDetails'
| 'editorPortalTarget'
+| 'overscanRowCount'
+| 'overscanColumnCount'
+| 'enableIsScrolling'
>;
type SharedDataGridState = Pick,
@@ -39,120 +41,99 @@ type SharedDataGridState = Pick,
>;
export interface GridProps extends SharedDataGridProps, SharedDataGridState {
- headerRows: HeaderRowData[];
+ headerRows: [HeaderRowData, HeaderRowData | undefined];
cellMetaData: CellMetaData;
selectedRows?: SelectedRow[];
rowSelection?: RowSelection;
rowOffsetHeight: number;
+ eventBus: EventBus;
+ interactionMasksMetaData: InteractionMasksMetaData;
onSort(columnKey: keyof R, sortDirection: DEFINE_SORT): void;
- totalWidth: number | string;
onViewportKeydown(e: React.KeyboardEvent): void;
onViewportKeyup(e: React.KeyboardEvent): void;
onColumnResize(idx: number, width: number): void;
- eventBus: EventBus;
- interactionMasksMetaData: InteractionMasksMetaData;
}
-export default class Grid extends React.Component> {
- static displayName = 'Grid';
-
- private readonly header = React.createRef>();
- private readonly viewport = React.createRef>();
- private _scrollLeft?: number = undefined;
-
- _onScroll() {
- if (this._scrollLeft !== undefined) {
- this.header.current!.setScrollLeft(this._scrollLeft);
- if (this.viewport.current) {
- this.viewport.current.setScrollLeft(this._scrollLeft);
- }
- }
- }
-
- areFrozenColumnsScrolledLeft(scrollLeft: number) {
- return scrollLeft > 0 && this.props.columnMetrics.columns.some(c => isFrozen(c));
- }
+export default function Grid({ emptyRowsView, headerRows, ...props }: GridProps) {
+ const isWidthInitialized = useRef(false);
+ const grid = useRef(null);
+ const header = useRef>(null);
+ const scrollLeft = useRef(0);
- onScroll = (scrollState: ScrollState) => {
- if (this.props.onScroll) {
- this.props.onScroll(scrollState);
+ function onScroll(scrollState: ScrollState) {
+ if (header.current && scrollLeft.current !== scrollState.scrollLeft) {
+ scrollLeft.current = scrollState.scrollLeft;
+ header.current.setScrollLeft(scrollState.scrollLeft);
}
- const { scrollLeft } = scrollState;
- if (this._scrollLeft !== scrollLeft || this.areFrozenColumnsScrolledLeft(scrollLeft)) {
- this._scrollLeft = scrollLeft;
- this._onScroll();
+ if (props.onScroll) {
+ props.onScroll(scrollState);
}
- };
-
- componentDidMount() {
- this._scrollLeft = this.viewport.current ? this.viewport.current.getScroll().scrollLeft : 0;
- this._onScroll();
}
- componentDidUpdate() {
- this._onScroll();
- }
-
- render() {
- const { headerRows } = this.props;
- const EmptyRowsView = this.props.emptyRowsView;
+ useEffect(() => {
+ // Delay rendering until width is initialized
+ // Width is needed to calculate the number of displayed columns
+ isWidthInitialized.current = true;
+ }, []);
- return (
-
-
- ref={this.header}
- columnMetrics={this.props.columnMetrics}
- onColumnResize={this.props.onColumnResize}
- rowHeight={this.props.rowHeight}
- totalWidth={this.props.totalWidth}
- headerRows={headerRows}
- sortColumn={this.props.sortColumn}
- sortDirection={this.props.sortDirection}
- draggableHeaderCell={this.props.draggableHeaderCell}
- onSort={this.props.onSort}
- onHeaderDrop={this.props.onHeaderDrop}
- getValidFilterValues={this.props.getValidFilterValues}
- cellMetaData={this.props.cellMetaData}
- />
- {this.props.rowsCount === 0 && isValidElementType(EmptyRowsView) ? (
-
-
-
- ) : (
-
-
- ref={this.viewport}
- rowKey={this.props.rowKey}
- rowHeight={this.props.rowHeight}
- rowRenderer={this.props.rowRenderer}
- rowGetter={this.props.rowGetter}
- rowsCount={this.props.rowsCount}
- selectedRows={this.props.selectedRows}
- columnMetrics={this.props.columnMetrics}
- totalWidth={this.props.totalWidth}
- onScroll={this.onScroll}
- cellMetaData={this.props.cellMetaData}
- rowOffsetHeight={this.props.rowOffsetHeight || this.props.rowHeight * headerRows.length}
- minHeight={this.props.minHeight}
- scrollToRowIndex={this.props.scrollToRowIndex}
- contextMenu={this.props.contextMenu}
- rowSelection={this.props.rowSelection}
- getSubRowDetails={this.props.getSubRowDetails}
- rowGroupRenderer={this.props.rowGroupRenderer}
- enableCellSelect={this.props.enableCellSelect}
- enableCellAutoFocus={this.props.enableCellAutoFocus}
- cellNavigationMode={this.props.cellNavigationMode}
- eventBus={this.props.eventBus}
- interactionMasksMetaData={this.props.interactionMasksMetaData}
- RowsContainer={this.props.RowsContainer}
- editorPortalTarget={this.props.editorPortalTarget}
- />
-
- )}
-
- );
- }
+ return (
+
+ );
}
diff --git a/packages/react-data-grid/src/Header.tsx b/packages/react-data-grid/src/Header.tsx
index 7662d7ea44..05dbf923f7 100644
--- a/packages/react-data-grid/src/Header.tsx
+++ b/packages/react-data-grid/src/Header.tsx
@@ -1,20 +1,17 @@
import React from 'react';
-import ReactDOM from 'react-dom';
import classNames from 'classnames';
import HeaderRow from './HeaderRow';
import { resizeColumn } from './ColumnMetrics';
-import getScrollbarSize from './getScrollbarSize';
-import { HeaderRowType } from './common/enums';
-import { CalculatedColumn, ColumnMetrics } from './common/types';
+import { getScrollbarSize } from './utils';
+import { CalculatedColumn, ColumnMetrics, HeaderRowData } from './common/types';
import { GridProps } from './Grid';
type SharedGridProps = Pick,
'columnMetrics'
| 'onColumnResize'
-| 'rowHeight'
-| 'totalWidth'
| 'headerRows'
+| 'rowOffsetHeight'
| 'sortColumn'
| 'sortDirection'
| 'draggableHeaderCell'
@@ -67,45 +64,38 @@ export default class Header extends React.Component, State>
this.props.onColumnResize(pos, width || column.width);
};
- getHeaderRows() {
+ getHeaderRow = (row: HeaderRowData, ref: React.RefObject>) => {
const columnMetrics = this.getColumnMetrics();
- return this.props.headerRows.map((row, index) => {
- // To allow header filters to be visible
- const isFilterRow = row.rowType === HeaderRowType.FILTER;
- const rowHeight = isFilterRow ? '500px' : 'auto';
- const scrollbarSize = getScrollbarSize() > 0 ? getScrollbarSize() : 0;
- const updatedWidth = typeof this.props.totalWidth === 'number'
- ? this.props.totalWidth - scrollbarSize
- : this.props.totalWidth;
- const headerRowStyle: React.CSSProperties = {
- top: this.getCombinedHeaderHeights(index),
- width: updatedWidth,
- minHeight: rowHeight
- };
-
- return (
-
- key={row.rowType}
- ref={isFilterRow ? this.filterRow : this.row}
- rowType={row.rowType}
- style={headerRowStyle}
- onColumnResize={this.onColumnResize}
- onColumnResizeEnd={this.onColumnResizeEnd}
- width={columnMetrics.width}
- height={row.height || this.props.rowHeight}
- columns={columnMetrics.columns}
- draggableHeaderCell={this.props.draggableHeaderCell}
- filterable={row.filterable}
- onFilterChange={row.onFilterChange}
- onHeaderDrop={this.props.onHeaderDrop}
- sortColumn={this.props.sortColumn}
- sortDirection={this.props.sortDirection}
- onSort={this.props.onSort}
- getValidFilterValues={this.props.getValidFilterValues}
- />
- );
- });
+ return (
+
+ key={row.rowType}
+ ref={ref}
+ rowType={row.rowType}
+ onColumnResize={this.onColumnResize}
+ onColumnResizeEnd={this.onColumnResizeEnd}
+ height={row.height}
+ columns={columnMetrics.columns}
+ draggableHeaderCell={this.props.draggableHeaderCell}
+ filterable={row.filterable}
+ onFilterChange={row.onFilterChange}
+ onHeaderDrop={this.props.onHeaderDrop}
+ sortColumn={this.props.sortColumn}
+ sortDirection={this.props.sortDirection}
+ onSort={this.props.onSort}
+ getValidFilterValues={this.props.getValidFilterValues}
+ />
+ );
+ };
+
+ getHeaderRows() {
+ const { headerRows } = this.props;
+ const rows = [this.getHeaderRow(headerRows[0], this.row)];
+ if (headerRows[1]) {
+ rows.push(this.getHeaderRow(headerRows[1], this.filterRow));
+ }
+
+ return rows;
}
getColumnMetrics(): ColumnMetrics {
@@ -121,25 +111,9 @@ export default class Header extends React.Component, State>
return idx === -1 ? null : idx;
}
- getCombinedHeaderHeights(until?: number): number {
- const stopAt = typeof until === 'number'
- ? until
- : this.props.headerRows.length;
-
- let height = 0;
- for (let index = 0; index < stopAt; index++) {
- height += this.props.headerRows[index].height || this.props.rowHeight;
- }
- return height;
- }
-
setScrollLeft(scrollLeft: number): void {
- const node = ReactDOM.findDOMNode(this.row.current) as Element;
- node.scrollLeft = scrollLeft;
this.row.current!.setScrollLeft(scrollLeft);
if (this.filterRow.current) {
- const nodeFilters = ReactDOM.findDOMNode(this.filterRow.current) as Element;
- nodeFilters.scrollLeft = scrollLeft;
this.filterRow.current.setScrollLeft(scrollLeft);
}
}
@@ -156,7 +130,10 @@ export default class Header extends React.Component, State>
return (
diff --git a/packages/react-data-grid/src/HeaderCell.tsx b/packages/react-data-grid/src/HeaderCell.tsx
index ad2c8bbda8..7d905a1df6 100644
--- a/packages/react-data-grid/src/HeaderCell.tsx
+++ b/packages/react-data-grid/src/HeaderCell.tsx
@@ -130,7 +130,7 @@ export default class HeaderCell
extends React.Component> {
removeScroll() {
const node = this.cell.current;
if (node) {
- node.style.transform = null;
+ node.style.transform = 'none';
}
}
diff --git a/packages/react-data-grid/src/HeaderRow.tsx b/packages/react-data-grid/src/HeaderRow.tsx
index e90c0188b6..823073b06f 100644
--- a/packages/react-data-grid/src/HeaderRow.tsx
+++ b/packages/react-data-grid/src/HeaderRow.tsx
@@ -1,10 +1,8 @@
import React from 'react';
-import shallowEqual from 'shallowequal';
import HeaderCell from './HeaderCell';
import SortableHeaderCell from './common/cells/headerCells/SortableHeaderCell';
import FilterableHeaderCell from './common/cells/headerCells/FilterableHeaderCell';
-import getScrollbarSize from './getScrollbarSize';
import { isFrozen } from './ColumnUtils';
import { HeaderRowType, HeaderCellType, DEFINE_SORT } from './common/enums';
import { CalculatedColumn, AddFilterEvent } from './common/types';
@@ -20,33 +18,21 @@ type SharedHeaderProps = Pick,
>;
export interface HeaderRowProps extends SharedHeaderProps {
- width?: number;
height: number;
columns: CalculatedColumn[];
onColumnResize(column: CalculatedColumn, width: number): void;
onColumnResizeEnd(column: CalculatedColumn, width: number): void;
- style?: React.CSSProperties;
filterable?: boolean;
onFilterChange?(args: AddFilterEvent): void;
rowType: HeaderRowType;
}
-export default class HeaderRow extends React.Component> {
+export default class HeaderRow extends React.PureComponent> {
static displayName = 'HeaderRow';
+ private readonly headerRow = React.createRef();
private readonly cells = new Map>();
- shouldComponentUpdate(nextProps: HeaderRowProps) {
- return (
- nextProps.width !== this.props.width
- || nextProps.height !== this.props.height
- || nextProps.columns !== this.props.columns
- || !shallowEqual(nextProps.style, this.props.style)
- || this.props.sortColumn !== nextProps.sortColumn
- || this.props.sortDirection !== nextProps.sortDirection
- );
- }
-
getHeaderCellType(column: CalculatedColumn): HeaderCellType {
if (column.filterable && this.props.filterable) {
return HeaderCellType.FILTERABLE;
@@ -134,6 +120,7 @@ export default class HeaderRow extends React.Component> {
}
setScrollLeft(scrollLeft: number): void {
+ this.headerRow.current!.scrollLeft = scrollLeft;
this.props.columns.forEach(column => {
const { key } = column;
if (!this.cells.has(key)) return;
@@ -147,20 +134,17 @@ export default class HeaderRow extends React.Component> {
}
render() {
- const cellsStyle: React.CSSProperties = {
- width: this.props.width ? this.props.width + getScrollbarSize() : '100%',
- height: this.props.height
- };
+ const { height, rowType } = this.props;
- // FIXME: do we need 2 wrapping divs?
return (
-
- {this.getCells()}
-
+ {this.getCells()}
);
}
diff --git a/packages/react-data-grid/src/ReactDataGrid.tsx b/packages/react-data-grid/src/ReactDataGrid.tsx
index a9e1516332..abb7c17639 100644
--- a/packages/react-data-grid/src/ReactDataGrid.tsx
+++ b/packages/react-data-grid/src/ReactDataGrid.tsx
@@ -156,6 +156,21 @@ export interface DataGridProps {
onCellDeSelected?(position: Position): void;
/** called before cell is set active, returns a boolean to determine whether cell is editable */
onCheckCellIsEditable?(event: CheckCellIsEditableEvent): boolean;
+ /**
+ * The number of rows to render outside of the visible area
+ * Note that overscanning too much can negatively impact performance. By default, grid overscans by two items.
+ */
+ overscanRowCount?: number;
+ /**
+ * The number of columns to render outside of the visible area
+ * Note that overscanning too much can negatively impact performance. By default, grid overscans by two items.
+ */
+ overscanColumnCount?: number;
+ /**
+ * Provides an additional isScrolling parameter to formatters. This parameter can be used to show a placeholder row or column while the list is being scrolled.
+ * Note that using this parameter will result in an additional render call after scrolling has stopped (when isScrolling changes from true to false).
+ */
+ enableIsScrolling?: boolean;
}
type DefaultProps = Pick,
@@ -212,7 +227,6 @@ export default class ReactDataGrid extends React.Component();
- private readonly base = React.createRef>();
private readonly selectAllCheckbox = React.createRef();
private readonly eventBus = new EventBus();
private readonly _keysDown = new Set();
@@ -264,14 +278,10 @@ export default class ReactDataGrid extends React.Component extends React.Component {
const columnMetrics = this.createColumnMetrics();
this.setState({ columnMetrics });
@@ -562,22 +568,17 @@ export default class ReactDataGrid extends React.Component offsetHeight += row.height, 0);
- }
-
- getHeaderRows() {
+ getHeaderRows(): [HeaderRowData, HeaderRowData | undefined] {
const { headerRowHeight, rowHeight, onAddFilter, headerFiltersHeight } = this.props;
- const rows: HeaderRowData[] = [{ height: headerRowHeight || rowHeight, rowType: HeaderRowType.HEADER }];
- if (this.state.canFilter === true) {
- rows.push({
+ return [
+ { height: headerRowHeight || rowHeight, rowType: HeaderRowType.HEADER },
+ this.state.canFilter ? {
rowType: HeaderRowType.FILTER,
filterable: true,
onFilterChange: onAddFilter,
- height: headerFiltersHeight
- });
- }
- return rows;
+ height: headerFiltersHeight || headerRowHeight || rowHeight
+ } : undefined
+ ];
}
getRowSelectionProps() {
@@ -668,21 +669,14 @@ export default class ReactDataGrid extends React.Component
@@ -692,9 +686,8 @@ export default class ReactDataGrid extends React.Component
- ref={this.base}
rowKey={this.props.rowKey}
- headerRows={this.getHeaderRows()}
+ headerRows={headerRows}
draggableHeaderCell={this.props.draggableHeaderCell}
getValidFilterValues={this.props.getValidFilterValues}
columnMetrics={this.state.columnMetrics}
@@ -706,12 +699,11 @@ export default class ReactDataGrid extends React.Component extends React.Component
);
diff --git a/packages/react-data-grid/src/Row.tsx b/packages/react-data-grid/src/Row.tsx
index a16523d25e..f3a0725304 100644
--- a/packages/react-data-grid/src/Row.tsx
+++ b/packages/react-data-grid/src/Row.tsx
@@ -5,6 +5,7 @@ import rowComparer from './common/utils/RowComparer';
import Cell from './Cell';
import { isFrozen } from './ColumnUtils';
import * as rowUtils from './RowUtils';
+import { isPositionStickySupported } from './utils';
import { RowRenderer, RowRendererProps, CellRenderer, CellRendererProps, CalculatedColumn } from './common/types';
export default class Row extends React.Component> implements RowRenderer {
@@ -43,7 +44,7 @@ export default class Row extends React.Component> impleme
getCell(column: CalculatedColumn) {
const Renderer = this.props.cellRenderer!;
- const { idx, cellMetaData, isScrolling, row, isSelected, scrollLeft, lastFrozenColumnIndex } = this.props;
+ const { idx, cellMetaData, isScrolling, row, lastFrozenColumnIndex, scrollLeft } = this.props;
const { key } = column;
const cellProps: CellRendererProps & { ref: (cell: CellRenderer | null) => void } = {
@@ -55,10 +56,9 @@ export default class Row extends React.Component> impleme
cellMetaData,
value: this.getCellValue(key || String(column.idx) as keyof R) as R[keyof R], // FIXME: fix types
rowData: row,
- isRowSelected: isSelected,
expandableOptions: this.getExpandableOptions(key),
isScrolling,
- scrollLeft,
+ scrollLeft: isFrozen(column) && !isPositionStickySupported() ? scrollLeft : undefined,
lastFrozenColumnIndex
};
@@ -66,8 +66,8 @@ export default class Row extends React.Component> impleme
}
getCells() {
- const { colOverscanStartIdx, colOverscanEndIdx, columns } = this.props;
- const frozenColumns = columns.filter(c => isFrozen(c));
+ const { colOverscanStartIdx, colOverscanEndIdx, columns, lastFrozenColumnIndex } = this.props;
+ const frozenColumns = columns.slice(0, lastFrozenColumnIndex + 1);
const nonFrozenColumn = columns.slice(colOverscanStartIdx, colOverscanEndIdx + 1).filter(c => !isFrozen(c));
return nonFrozenColumn.concat(frozenColumns).map(c => this.getCell(c));
}
diff --git a/packages/react-data-grid/src/RowGroup.tsx b/packages/react-data-grid/src/RowGroup.tsx
index d092de587f..ac72b14ffb 100644
--- a/packages/react-data-grid/src/RowGroup.tsx
+++ b/packages/react-data-grid/src/RowGroup.tsx
@@ -20,7 +20,7 @@ interface Props {
colVisibleEndIdx: number;
colOverscanStartIdx: number;
colOverscanEndIdx: number;
- isScrolling: boolean;
+ isScrolling?: boolean;
columnGroupDisplayName: string;
columnGroupName: string;
isExpanded: boolean;
diff --git a/packages/react-data-grid/src/Viewport.tsx b/packages/react-data-grid/src/Viewport.tsx
index 7d251d2364..0055197b0a 100644
--- a/packages/react-data-grid/src/Viewport.tsx
+++ b/packages/react-data-grid/src/Viewport.tsx
@@ -1,45 +1,15 @@
-import React from 'react';
+import React, { useRef, useState, useMemo } from 'react';
import Canvas from './Canvas';
-import {
- getGridState,
- getColOverscanEndIdx,
- getVisibleBoundaries,
- getScrollDirection,
- getRowOverscanStartIdx,
- getRowOverscanEndIdx,
- getColOverscanStartIdx,
- getNonFrozenVisibleColStartIdx,
- getNonFrozenRenderedColumnCount,
- findLastFrozenColumnIndex
-} from './utils/viewportUtils';
+import { getVerticalRangeToRender, getHorizontalRangeToRender, getScrollDirection } from './utils/viewportUtils';
import { GridProps } from './Grid';
import { ScrollPosition } from './common/types';
import { SCROLL_DIRECTION } from './common/enums';
-interface ScrollParams {
- height: number;
- scrollTop: number;
- scrollLeft: number;
- rowsCount: number;
- rowHeight: number;
-}
-
export interface ScrollState {
- height: number;
scrollTop: number;
scrollLeft: number;
- rowVisibleStartIdx: number;
- rowVisibleEndIdx: number;
- rowOverscanStartIdx: number;
- rowOverscanEndIdx: number;
- colVisibleStartIdx: number;
- colVisibleEndIdx: number;
- colOverscanStartIdx: number;
- colOverscanEndIdx: number;
scrollDirection: SCROLL_DIRECTION;
- lastFrozenColumnIndex: number;
- isScrolling: boolean;
}
type SharedGridProps = Pick,
@@ -50,7 +20,6 @@ type SharedGridProps = Pick,
| 'rowsCount'
| 'selectedRows'
| 'columnMetrics'
-| 'totalWidth'
| 'cellMetaData'
| 'rowOffsetHeight'
| 'minHeight'
@@ -66,233 +35,134 @@ type SharedGridProps = Pick,
| 'interactionMasksMetaData'
| 'RowsContainer'
| 'editorPortalTarget'
+| 'overscanRowCount'
+| 'overscanColumnCount'
+| 'enableIsScrolling'
+| 'onViewportKeydown'
+| 'onViewportKeyup'
>;
export interface ViewportProps extends SharedGridProps {
onScroll(scrollState: ScrollState): void;
+ viewportWidth: number;
}
-export interface ViewportState {
- rowOverscanStartIdx: number;
- rowOverscanEndIdx: number;
- rowVisibleStartIdx: number;
- rowVisibleEndIdx: number;
- height: number;
- scrollTop: number;
- scrollLeft: number;
- colVisibleStartIdx: number;
- colVisibleEndIdx: number;
- colOverscanStartIdx: number;
- colOverscanEndIdx: number;
- isScrolling: boolean;
- lastFrozenColumnIndex: number;
-}
-
-export default class Viewport extends React.Component, ViewportState> {
- static displayName = 'Viewport';
-
- readonly state: Readonly = getGridState(this.props);
- private readonly canvas = React.createRef