All files / app/components ExtendingList.tsx

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113                                4x           4x         4x       4x           2x               2x 2x 2x   2x     2x                           2x 2x 2x           14x           2x                   2x     2x                                      
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,
      });
    }
  };
}