Reputation: 411
Problem : Getting double Scrollbars - Removing Paper Scrollbar makes the autocomplete content not scrollable hence showing ONLY the contents in the visible height of the dropdown. If I hide the other scroll then the Infinite Scroll API does not get invoked. How can I get it working :
Description -
I am trying to create a Infinite Scroll with Material UI Autocomplete for which I am using react-infinite-scroll-component attached link for reference
The way I implemented is :
As we need to attach the Infinite Scroll to the Popper that renders the list items; hence I have written my custom PAPER Component (as per documentation it is responsible for rendering items in the dropdown ) PaperComponent={myCustomComponent}
My InfiniteScrollAutoComplete definition is attached below :
<Autocomplete
options={list.data && list.data !== null ? list.data : []}
getOptionLabel={(option) => option.name}
PaperComponent={(param) => (
<InfiniteScroll
height={200}
dataLength={list.total}
next={this.handleFetchNext.bind(this)}
hasMore={list.data.length < list.total ? true : false}
loader={
<p style={{ textAlign: "center", backgroundColor: "#f9dc01" }}>
<b>Loading...</b>
</p>
}
endMessage={
<p style={{ textAlign: "center", backgroundColor: "#f9dc01" }}>
<b>Yay! You have seen it all</b>
</p>
}
>
<Paper {...param} />
</InfiniteScroll>
)}
renderInput={(params) => (
<TextField {...params} label="" variant="outlined" />
)}
/>
Upvotes: 5
Views: 9406
Reputation: 21
You need to implement your own list in the PaperComponent and ignore the param object:
PaperComponent={
() => {
return <Paper id={paperId}>
<InfiniteScroll
dataLength={data.length}
next={this.loadNext.bind(this)}
hasMore={hasMorePages}
loader={<h4 style={{ textAlign: 'center' }}>Loading ...</h4>}
height={400}
>
<List>
{data && data.map(value => <ListItem disablePadding>
<ListItemButton onMouseDown={(event) => this.handleSelected(event, value)}>
<ListItemText primary={value.name} />
</ListItemButton>
</ListItem>
)}
{data && data.length === 0 && <ListItem disablePadding>
<ListItemButton disabled>
<ListItemText primary="No items available" />
</ListItemButton>
</ListItem>}
</List>
</InfiniteScroll>
</Paper>
}
}
Be sure to use onMouseDown event handler instead of onClick, otherwise selecting an item won't work.
Upvotes: 0
Reputation: 1
const observer = useRef();
const lastOptionElementRef = useCallback((node) => {
if (observer.current) observer.current.disconnect();
observer.current = new IntersectionObserver(async (entries) => {
if (entries[0].isIntersecting && props.hasMore) {
setPageNumber((pageNumber) => pageNumber + 1);
}
});
if (node) observer.current.observe(node);
}, [props.loader]);
you can add this lastOptionElementRef to the last element of the options using the render option prop. This will trigger an function whenever the last option is visible in the viewport. Also, it avoids the scrolling issue
Upvotes: 0