Skip to content

Commit

Permalink
virtualized sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
priley86 committed Jan 25, 2019
1 parent 3cd8725 commit f720dbb
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,27 @@ class Body extends React.Component {
super(props);

this.measuredRows = {}; // row key -> measurement
this.ref = null;

this.ref = React.createRef();

this.scrollTo = index => {
const startIndex = parseInt(index, 10);

if (startIndex >= 0) {
const startHeight =
calculateAverageHeight({
measuredRows: this.measuredRows,
rows: props.rows,
rowKey: props.rowKey
}) * startIndex;

this.scrollTop = startHeight;
this.ref.current.scrollTop = startHeight;

this.setState(this.calculateRows(this.props));
}
};

this.scrollTop = 0;
this.initialMeasurement = true;
this.timeoutId = 0;
Expand Down Expand Up @@ -58,6 +78,7 @@ class Body extends React.Component {
return props.height || props.style.maxHeight;
}

// todo: convert `componentWillReceiveProps` to `getDerivedStateFromProps`
componentWillReceiveProps(nextProps) {
if (!isEqual(this.props.rows, nextProps.rows) || this.getHeight(this.props) !== this.getHeight(nextProps)) {
if (process.env.NODE_ENV !== 'production' && typeof window !== 'undefined' && window.LOG_VIRTUALIZED) {
Expand Down Expand Up @@ -120,16 +141,13 @@ class Body extends React.Component {
};
},
rowsToRender,
// todo: revisit passing ref to scrolling container and finding offset
// ref: body => {
// this.ref = body && body.getRef().getRef();
// },
onScroll: this.onScroll
});

return (
<VirtualizedBodyContext.Provider
value={{
bodyRef: this.ref,
startHeight,
endHeight,
showExtraRow,
Expand All @@ -146,7 +164,7 @@ class Body extends React.Component {
}

getBodyOffset() {
return this.ref.parentElement.offsetTop + this.ref.offsetTop;
return this.ref.current.parentElement.offsetTop + this.ref.current.offsetTop;
}

onScroll(e) {
Expand All @@ -166,29 +184,29 @@ class Body extends React.Component {

this.setState(this.calculateRows(this.props));
}
getRef() {
const { ref } = this;
// getRef() {
// const { ref } = this;

ref.scrollTo = index => {
const startIndex = parseInt(index, 10);
// ref.scrollTo = index => {
// const startIndex = parseInt(index, 10);

if (startIndex >= 0) {
const startHeight =
calculateAverageHeight({
measuredRows: this.measuredRows,
rows: this.props.rows,
rowKey: this.props.rowKey
}) * startIndex;
// if (startIndex >= 0) {
// const startHeight =
// calculateAverageHeight({
// measuredRows: this.measuredRows,
// rows: this.props.rows,
// rowKey: this.props.rowKey
// }) * startIndex;

this.scrollTop = startHeight;
this.ref.scrollTop = startHeight;
// this.scrollTop = startHeight;
// this.ref.scrollTop = startHeight;

this.setState(this.calculateRows(this.props));
}
};
// this.setState(this.calculateRows(this.props));
// }
// };

return ref;
}
// return ref;
// }
calculateRows(props) {
return calculateRows({
scrollTop: this.scrollTop,
Expand Down Expand Up @@ -223,7 +241,7 @@ class Body extends React.Component {

const VirtualizedBody = props => (
<TableContext.Consumer>
{({ headerData, rows }) => <Body {...props} headerData={headerData} rows={rows} />}
{({ headerData, rows }) => <Body {...props} ref={props.tableBody} headerData={headerData} rows={rows} />}
</TableContext.Consumer>
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ const VirtualizedBodyWrapper = inputRows => {
class VirtualizedBody extends Component {
constructor(props) {
super(props);
this.ref = React.createRef();
}
render() {
const { children, startHeight, endHeight, showExtraRow, ...props } = this.props;
const { children, bodyRef, startHeight, endHeight, showExtraRow, ...props } = this.props;
const startRow = tr({
key: 'start-row',
style: {
Expand Down Expand Up @@ -43,7 +42,7 @@ const VirtualizedBodyWrapper = inputRows => {
'tbody',
{
...props,
ref: this.ref,
ref: bodyRef,
className: css(
inputRows.some(row => row.isOpen && !row.hasOwnProperty('parent')) && styles.modifiers.expanded
)
Expand All @@ -52,7 +51,7 @@ const VirtualizedBodyWrapper = inputRows => {
);
}
getRef() {
return this.ref;
return this.props.tableBodyRef;
}
}
VirtualizedBodyWrapper.contextTypes = bodyWrapperContextTypes;
Expand All @@ -64,8 +63,14 @@ const VirtualizedBodyWrapper = inputRows => {

const VirtualizedBodyWithContext = props => (
<VirtualizedBodyContext.Consumer>
{({ startHeight, endHeight, showExtraRow }) => (
<VirtualizedBody {...props} startHeight={startHeight} endHeight={endHeight} showExtraRow={showExtraRow} />
{({ bodyRef, startHeight, endHeight, showExtraRow }) => (
<VirtualizedBody
{...props}
bodyRef={bodyRef}
startHeight={startHeight}
endHeight={endHeight}
showExtraRow={showExtraRow}
/>
)}
</VirtualizedBodyContext.Consumer>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
import { AutoSizer } from '@patternfly/react-virtualized-extension';
import {
AutoSizer,
VirtualizedBody,
VirtualizedBodyWrapper,
VirtualizedRowWrapper
} from '@patternfly/react-virtualized-extension';
import AutoSizerExample from './examples/AutoSizerExample';
import VirtualizedExample from './examples/VirtualizedExample';
import SortableExample from './examples/SortableExample';

export default {
title: 'Virtualized',
components: {
AutoSizer
AutoSizer,
VirtualizedBody,
VirtualizedBodyWrapper,
VirtualizedRowWrapper
},
examples: [
{ component: AutoSizerExample, title: 'Simple AutoSizer Example' },
{ component: VirtualizedExample, title: 'Simple Virtualized Example' }
{ component: VirtualizedExample, title: 'Simple Virtualized Example' },
{ component: SortableExample, title: 'Sortable Virtualized Example' }
]
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React from 'react';
import { Table, TableHeader, sortable, SortByDirection } from '@patternfly/react-table';
import {
VirtualizedBody,
VirtualizedBodyWrapper,
VirtualizedRowWrapper
} from '@patternfly/react-virtualized-extension';
import './sample.css';

class SortableExample extends React.Component {
static title = 'Simple Table';
constructor(props) {
super(props);

this.tableBody = React.createRef();

const rows = [];
for (let i = 0; i < 100; i++) {
rows.push({
id: i,
cells: [`one-${i}`, `two-${i}`, `three-${i}`, `four-${i}`, `five-${i}`]
});
}
this.state = {
columns: [
{ title: 'Repositories', transforms: [sortable], props: { style: { width: '20%' } } },
{ title: 'Branches', props: { style: { width: '20%' } } },
{ title: 'Pull requests', transforms: [sortable], props: { style: { width: '20%' } } },
{ title: 'Workspaces', props: { style: { width: '20%' } } },
{ title: 'Last Commit', props: { style: { width: '20%' } } }
],
rows,
sortBy: {}
};
this.onSort = this.onSort.bind(this);
}

onSort(_event, index, direction) {
const sortedRows = this.state.rows.sort(
(a, b) => (a.cells[index] < b.cells[index] ? -1 : a.cells[index] > b.cells[index] ? 1 : 0)
);
this.tableBody.current.scrollTo(0);
this.setState({
sortBy: {
index,
direction
},
rows: direction === SortByDirection.asc ? sortedRows : sortedRows.reverse()
});
}

render() {
const { columns, rows, sortBy } = this.state;

return (
<Table
caption="Sortable Virtualized Table"
cells={columns}
rows={rows}
bodyWrapper={VirtualizedBodyWrapper}
rowWrapper={VirtualizedRowWrapper}
sortBy={sortBy}
onSort={this.onSort}
>
<TableHeader />
<VirtualizedBody height={400} rowKey="id" tableBody={this.tableBody} />
</Table>
);
}
}

export default SortableExample;

0 comments on commit f720dbb

Please sign in to comment.