@@ -34,6 +34,7 @@ export interface InfiniteScrollProps {
3434 ContentWrapper ?: React . FC < React . PropsWithChildren > ;
3535 /** Additional props passed to the intersection observer element */
3636 intersectionElementProps ?: React . ComponentPropsWithoutRef < "div" > ;
37+ mode ?: "infinite" | "enable-once" | "pagination" ;
3738}
3839
3940export const InfiniteScroll : React . FC < React . PropsWithChildren < InfiniteScrollProps > > = ( {
@@ -50,10 +51,11 @@ export const InfiniteScroll: React.FC<React.PropsWithChildren<InfiniteScrollProp
5051 loadMoreButton = "Load more" ,
5152 ContentWrapper = defaultContentWrapper ,
5253 intersectionElementProps,
54+ mode = loadMoreButton ? "enable-once" : "infinite" ,
5355} ) => {
5456 const intersectionRef = useRef < HTMLDivElement > ( null ) ;
5557
56- const [ infiniteScrollEnabled , setInfiniteScrollEnabled ] = useState ( ! displayLoadMore ) ;
58+ const [ infiniteScrollEnabled , setInfiniteScrollEnabled ] = useState ( mode === "infinite" ) ;
5759 const [ isIntersecting , setIsIntersecting ] = useState ( false ) ;
5860
5961 const hasItemsLeft = useMemo (
@@ -63,25 +65,28 @@ export const InfiniteScroll: React.FC<React.PropsWithChildren<InfiniteScrollProp
6365
6466 const LoadMoreButton = useMemo ( ( ) => {
6567 if ( ! displayLoadMore ) return null ;
68+
69+ const action = ( ) => {
70+ if ( mode === "enable-once" ) {
71+ setInfiniteScrollEnabled ( true ) ;
72+ } else {
73+ if ( loading ) return ;
74+ void onLoadMore ( ) ;
75+ }
76+ } ;
77+
6678 if ( typeof loadMoreButton === "function" ) {
6779 return loadMoreButton ( {
68- loadMore : ( ) => {
69- setInfiniteScrollEnabled ( true ) ;
70- } ,
80+ loadMore : action ,
7181 } ) ;
7282 }
7383
7484 return (
75- < Button
76- skinVariation = "bordered"
77- fullWidth
78- onClick = { ( ) => {
79- setInfiniteScrollEnabled ( true ) ;
80- } } >
85+ < Button skinVariation = "bordered" fullWidth onClick = { action } >
8186 { loadMoreButton }
8287 </ Button >
8388 ) ;
84- } , [ loadMoreButton , displayLoadMore ] ) ;
89+ } , [ displayLoadMore , loadMoreButton , loading , mode , onLoadMore ] ) ;
8590
8691 const elements = useMemo < React . ReactNode [ ] > ( ( ) => {
8792 const elements = [
@@ -94,7 +99,9 @@ export const InfiniteScroll: React.FC<React.PropsWithChildren<InfiniteScrollProp
9499 </ ContentWrapper >
95100 ) : null ,
96101 hasItemsLeft && loadingMore ? ( loadingMoreElement ?? < Spinner /> ) : null ,
97- displayLoadMore && ! infiniteScrollEnabled && hasItemsLeft ? LoadMoreButton : null ,
102+ displayLoadMore && ! infiniteScrollEnabled && hasItemsLeft && ! loading && ! loadingMore
103+ ? LoadMoreButton
104+ : null ,
98105 ] ;
99106
100107 return direction === "bottom" ? elements : elements . reverse ( ) ;
0 commit comments