The useWindowedContainer hook will create a host for multiple useWindowedList hooks working with the same container node. It will be helpful for windowing complex components such diff screens of git hosting tools.
The hook signature will look similar to this:
type UseWindowedContainer = <E extends HTMLElement>(options: {
containerSize: number
layout?: ListLayout
initialScroll?: number
containerOnScrollThrottleInterval?: number
containerIsScrollingDebounceInterval?: number
}) => {
isScrolling: boolean
container: null | E
setContainerRef(node: null | E): void
scrollTo(px: number): void
useWindowedListInContainer: UseWindowedListInContainer
}
And the UseWindowedListInContainer signature:
type UseWindowedListInContainer = (options: {
itemSize: ItemSize
itemCount: number
overscanCount?: number
firstItemStartAt?: number
onItemsRendered?(renderedRange: ListRenderedRange): void
}) => {
overscanFromIndex: number
overscanBeforeIndex: number
visibleFromIndex: number
visibleBeforeIndex: number
startSpace: number
endSpace: number
indexes: ReadonlyArray<number>
}
So this way everything related to a container will be handled in useWindowedContainer and the rest of the stuff related to list and items itself is per useWindowedListInContainer. This way it will define on scroll listeners only once per container node and exclude conflict of initialScroll properties.
const WindowedContainer = ({ itemsA, itemsB }) => {
const { setContainerRef, useWindowedListInContainer } = useWindowedContainer({
containerSize: 1000
})
const listA = useWindowedListInContainer({
itemSize: 20,
itemCount: itemsA.length
})
const listB = useWindowedListInContainer({
firstItemStartAt: 20 * itemsA.length,
itemSize: 50,
itemCount: itemsB.length
})
return (
<div className="scrollable-container" ref={setContainerRef}>
<div>
<div style={{ height: itemsA.startSpace }} />
{listA
.map(index => itemsA[index])
.map(itemA => (
<ItemAComponent key={itemA.id} item={itemA} />
))}
<div style={{ height: itemsA.endSpace }} />
</div>
<div>
<div style={{ height: itemsB.startSpace }} />
{listB
.map(index => itemsB[index])
.map(itemB => (
<ItemBComponent key={itemB.id} item={itemB} />
))}
<div style={{ height: itemsB.endSpace }} />
</div>
</div>
)
}
The basic useWindowedList hook will be a special case of useWindowedContainer with improved initialScroll and added scrollToItem.
The
useWindowedContainerhook will create a host for multipleuseWindowedListhooks working with the same container node. It will be helpful for windowing complex components such diff screens of git hosting tools.The hook signature will look similar to this:
And the
UseWindowedListInContainersignature:So this way everything related to a container will be handled in
useWindowedContainerand the rest of the stuff related to list and items itself is peruseWindowedListInContainer. This way it will defineon scrolllisteners only once per container node and exclude conflict ofinitialScrollproperties.The basic
useWindowedListhook will be a special case ofuseWindowedContainerwith improvedinitialScrolland addedscrollToItem.