import React from 'react';
import { style } from 'app/styles';
import { SpinnerImage } from 'app/components/SpinnerImage';
import { request } from 'http';
export interface ExtendingListProps {
rowCount: number;
rowRenderer: (index: number, key: number | string) => any;
style?: object | string;
}
interface ExtendingListState {
itemsToRender: number;
}
const outerStyle = {
display: 'flex',
flexDirection: 'column',
overflow: 'auto',
};
const innerStyle = {
display: 'flex',
flexDirection: 'column',
};
const itemStyle = {
flexShrink: 0,
};
const PAGE_SIZE = 20;
export class ExtendingList extends React.Component<
ExtendingListProps,
ExtendingListState
> {
readonly state: ExtendingListState = { itemsToRender: PAGE_SIZE };
private outerContainerRef;
private innerContainerRef;
private rowsRendered;
// componentDidUpdate(newProps) {}
constructor(props) {
super(props);
this.innerContainerRef = React.createRef();
this.outerContainerRef = React.createRef();
this.onScroll = this.onScroll.bind(this);
}
render() {
return (
<div
style={style(outerStyle, this.props.style)}
ref={this.outerContainerRef}
onScroll={this.onScroll}
>
<div style={style(innerStyle)} ref={this.innerContainerRef}>
{this.renderRows()}
</div>
</div>
);
}
renderRows(): any {
this.rowsRendered = 0;
const rows = [];
for (
;
this.rowsRendered < this.state.itemsToRender &&
this.rowsRendered < this.props.rowCount;
this.rowsRendered++
) {
rows.push(
<div style={style(itemStyle)} key={this.rowsRendered}>
{this.props.rowRenderer(this.rowsRendered, `row${this.rowsRendered}`)}
</div>
);
}
Iif (this.rowsRendered < this.props.rowCount) {
rows.push(
<div
style={{ flexShrink: 0, textAlign: 'center', padding: 10 }}
key={this.rowsRendered + 1}
>
<SpinnerImage height={40} width={40} />
</div>
);
}
return rows;
}
onScroll = () => {
const innerEl = this.innerContainerRef.current;
const outerEl = this.outerContainerRef.current;
if (this.rowsRendered >= this.props.rowCount) {
return;
}
const innerBoundingRect = innerEl.getBoundingClientRect();
if (
innerEl.scrollHeight > outerEl.clientHeight &&
outerEl.scrollTop + outerEl.clientHeight > innerEl.scrollHeight - 200
) {
this.setState({
itemsToRender: this.state.itemsToRender + PAGE_SIZE,
});
}
};
}
|