Skip to content

Commit 3b52061

Browse files
Add infinite scrolling (#59)
1 parent 4fed477 commit 3b52061

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

src/components/LazyLog/index.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,10 @@ export interface LazyLogProps {
201201
* Specify an additional className to append to lines.
202202
*/
203203
lineClassName?: string;
204+
/**
205+
* Manually display the loading component
206+
*/
207+
loading?: boolean;
204208
/**
205209
* Specify an alternate component to use when loading.
206210
*/
@@ -244,6 +248,13 @@ export interface LazyLogProps {
244248
clientHeight: number;
245249
}): void;
246250

251+
/**
252+
* Callback invoked when visible items range changes.
253+
* @param startIndex - The start index of viewable items.
254+
* @param endIndex - The end index of viewable items.
255+
*/
256+
onRangeChange?(startIndex: number, endIndex: number): void;
257+
247258
/**
248259
* Number of rows to render above/below the visible bounds of the list.
249260
* This can help reduce flickering during scrolling on
@@ -368,6 +379,8 @@ export default class LazyLog extends Component<LazyLogProps, LazyLogState> {
368379
onHighlight: undefined,
369380
onLineNumberClick: undefined,
370381
onLoad: undefined,
382+
onRangeChange: undefined,
383+
loading: undefined,
371384
overscanRowCount: 100,
372385
rowHeight: 19,
373386
scrollToLine: 0,
@@ -1229,13 +1242,16 @@ export default class LazyLog extends Component<LazyLogProps, LazyLogState> {
12291242
this.props.onScroll(args);
12301243
}
12311244
}}
1245+
onRangeChange={this.props.onRangeChange}
12321246
>
12331247
{Array.from({
12341248
length:
12351249
rowCount === 0
12361250
? rowCount
12371251
: rowCount + (this.props.extraLines || 0),
12381252
}).map((_, i) => this.renderRow({ index: i }))}
1253+
{this.props.loading === true &&
1254+
(this.props.loadingComponent || <Loading />)}
12391255
</VList>
12401256
</Fragment>
12411257
);

src/stories/LazyLog.stories.tsx

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,3 +719,59 @@ export const LineWrapping: Story = {
719719
[taskcluster 2018-11-14 21:19:42.433Z] Successful task run with exit code: 0 completed in 669.981 seconds`,
720720
},
721721
};
722+
723+
const delay = (time: number) => {
724+
return new Promise((res) => {
725+
setTimeout(res, time);
726+
});
727+
};
728+
729+
export const InfiniteScrolling: Story = {
730+
args: {
731+
...BaseStory,
732+
height: 400,
733+
},
734+
render: (args) => {
735+
const createLines = (num: number, offset: number = 0) => {
736+
return Array.from({
737+
length: num,
738+
}).map((_, i) => {
739+
i += offset;
740+
return `Line: ${i}\n`;
741+
});
742+
};
743+
const [fetching, setFetching] = React.useState(false);
744+
745+
const fetchItems = async () => {
746+
setFetching(true);
747+
await delay(1000);
748+
setFetching(false);
749+
};
750+
751+
const ITEM_BATCH_COUNT = 100;
752+
const [items, setItems] = React.useState(() =>
753+
createLines(ITEM_BATCH_COUNT)
754+
);
755+
756+
const fetchedCountRef = React.useRef(-1);
757+
const count = items.length;
758+
759+
return (
760+
<LazyLog
761+
{...args}
762+
onRangeChange={async (_, end) => {
763+
if (end + 50 > count && fetchedCountRef.current < count) {
764+
fetchedCountRef.current = count;
765+
await fetchItems();
766+
setItems((prev) => [
767+
...prev,
768+
...createLines(ITEM_BATCH_COUNT, prev.length),
769+
]);
770+
}
771+
}}
772+
loading={fetching}
773+
text={items.join("")}
774+
></LazyLog>
775+
);
776+
},
777+
};

0 commit comments

Comments
 (0)