From f02b8162808803b8268619bc61e21b81b42cc7d2 Mon Sep 17 00:00:00 2001 From: Rom Orlovich Date: Tue, 5 Sep 2023 20:00:16 +0300 Subject: [PATCH 1/6] feat(hook): use the isInverse condition to decide whatever to scroll down or up to get the data --- packages/hooks/src/useInfiniteScroll/index.tsx | 7 +++++-- packages/hooks/src/useInfiniteScroll/types.ts | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/hooks/src/useInfiniteScroll/index.tsx b/packages/hooks/src/useInfiniteScroll/index.tsx index a559c562d1..a1b2a02d9e 100644 --- a/packages/hooks/src/useInfiniteScroll/index.tsx +++ b/packages/hooks/src/useInfiniteScroll/index.tsx @@ -16,6 +16,7 @@ const useInfiniteScroll = ( isNoMore, threshold = 100, reloadDeps = [], + isInverse, manual, onBefore, onSuccess, @@ -98,8 +99,10 @@ const useInfiniteScroll = ( const scrollTop = getScrollTop(el); const scrollHeight = getScrollHeight(el); const clientHeight = getClientHeight(el); - - if (scrollHeight - scrollTop <= clientHeight + threshold) { + const isScrollDown = scrollHeight - scrollTop <= clientHeight + threshold; + const isScrollUp = scrollTop + scrollHeight <= clientHeight + threshold; + const condition = isInverse ? isScrollUp : isScrollDown; + if (condition) { loadMore(); } }; diff --git a/packages/hooks/src/useInfiniteScroll/types.ts b/packages/hooks/src/useInfiniteScroll/types.ts index 7687e6ff60..fcb6a40583 100644 --- a/packages/hooks/src/useInfiniteScroll/types.ts +++ b/packages/hooks/src/useInfiniteScroll/types.ts @@ -23,7 +23,7 @@ export interface InfiniteScrollOptions { target?: BasicTarget; isNoMore?: (data?: TData) => boolean; threshold?: number; - + isInverse?: boolean; manual?: boolean; reloadDeps?: DependencyList; From 29db4a39c669ac3823fd12e64518cf606b26b740 Mon Sep 17 00:00:00 2001 From: Rom Orlovich Date: Tue, 5 Sep 2023 20:31:35 +0300 Subject: [PATCH 2/6] feat(hook-test): add test for auto load when scroll to top for useInfiniteScroll --- .../useInfiniteScroll/__tests__/index.test.ts | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/packages/hooks/src/useInfiniteScroll/__tests__/index.test.ts b/packages/hooks/src/useInfiniteScroll/__tests__/index.test.ts index 12d0c8654b..2f2f82f414 100644 --- a/packages/hooks/src/useInfiniteScroll/__tests__/index.test.ts +++ b/packages/hooks/src/useInfiniteScroll/__tests__/index.test.ts @@ -125,6 +125,60 @@ describe('useInfiniteScroll', () => { mockAddEventListener.mockRestore(); }); + it('should auto load when scroll to top', async () => { + const events = {}; + const mockAddEventListener = jest + .spyOn(targetEl, 'addEventListener') + .mockImplementation((eventName, callback) => { + events[eventName] = callback; + }); + const { result } = setup(mockRequest, { + target: targetEl, + isNoMore: (d) => d?.nextId === undefined, + isInverse: true, + }); + expect(result.current.loading).toBe(true); + + events['scroll'](); + + await act(async () => { + jest.advanceTimersByTime(1000); + }); + expect(result.current.loading).toBe(false); + // mock scroll + const currentTargetPosition = { + clientHeight: { + value: 400, + }, + scrollHeight: { + value: 300, + }, + scrollTop: { + value: 100, + }, + }; + Object.defineProperties(targetEl, currentTargetPosition); + + act(() => { + events['scroll'](); + }); + + expect(result.current.loadingMore).toBe(true); + await act(async () => { + jest.advanceTimersByTime(1000); + }); + expect(result.current.loadingMore).toBe(false); + + // not work when no more + expect(result.current.noMore).toBe(true); + act(() => { + events['scroll'](); + }); + expect(result.current.loadingMore).toBe(false); + + mockAddEventListener.mockRestore(); + }); + it('reload should be work', async () => { const fn = jest.fn(() => Promise.resolve({ list: [] })); const { result } = setup(fn); From f2e1deb073fb46789fc7aa4a3ad500b0dc875b49 Mon Sep 17 00:00:00 2001 From: Rom Orlovich Date: Tue, 5 Sep 2023 22:16:31 +0300 Subject: [PATCH 3/6] feat(useInfiniteScroll): rename variables in shouldLoadMore checking to isReachBoundary --- packages/hooks/src/useInfiniteScroll/index.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/hooks/src/useInfiniteScroll/index.tsx b/packages/hooks/src/useInfiniteScroll/index.tsx index a1b2a02d9e..ba8c1edffb 100644 --- a/packages/hooks/src/useInfiniteScroll/index.tsx +++ b/packages/hooks/src/useInfiniteScroll/index.tsx @@ -99,10 +99,10 @@ const useInfiniteScroll = ( const scrollTop = getScrollTop(el); const scrollHeight = getScrollHeight(el); const clientHeight = getClientHeight(el); - const isScrollDown = scrollHeight - scrollTop <= clientHeight + threshold; - const isScrollUp = scrollTop + scrollHeight <= clientHeight + threshold; - const condition = isInverse ? isScrollUp : isScrollDown; - if (condition) { + const isReachToBottom = scrollHeight - scrollTop <= clientHeight + threshold; + const isReachToTop = scrollTop + scrollHeight <= clientHeight + threshold; + const isReachBoundary = isInverse ? isReachToTop : isReachToBottom; + if (isReachBoundary) { loadMore(); } }; From a4e10ddbbbf67fa963748568e91a6de4dc7abdb7 Mon Sep 17 00:00:00 2001 From: Rom Orlovich Date: Tue, 5 Sep 2023 22:25:59 +0300 Subject: [PATCH 4/6] feat(useInfiniteScroll): name the calculation of clientHeight + threshold; --- packages/hooks/src/useInfiniteScroll/index.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/hooks/src/useInfiniteScroll/index.tsx b/packages/hooks/src/useInfiniteScroll/index.tsx index ba8c1edffb..583da9660d 100644 --- a/packages/hooks/src/useInfiniteScroll/index.tsx +++ b/packages/hooks/src/useInfiniteScroll/index.tsx @@ -99,8 +99,9 @@ const useInfiniteScroll = ( const scrollTop = getScrollTop(el); const scrollHeight = getScrollHeight(el); const clientHeight = getClientHeight(el); - const isReachToBottom = scrollHeight - scrollTop <= clientHeight + threshold; - const isReachToTop = scrollTop + scrollHeight <= clientHeight + threshold; + const scrollBoundary = clientHeight + threshold; + const isReachToBottom = scrollHeight - scrollTop <= scrollBoundary; + const isReachToTop = scrollTop + scrollHeight <= scrollBoundary; const isReachBoundary = isInverse ? isReachToTop : isReachToBottom; if (isReachBoundary) { loadMore(); From 2b52fe5803df07c0901e60002ee9b36d2622e82a Mon Sep 17 00:00:00 2001 From: Rom Orlovich Date: Tue, 5 Sep 2023 22:27:06 +0300 Subject: [PATCH 5/6] feat(useInfiniteScroll): add spaces --- packages/hooks/src/useInfiniteScroll/index.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/hooks/src/useInfiniteScroll/index.tsx b/packages/hooks/src/useInfiniteScroll/index.tsx index 583da9660d..edaded520e 100644 --- a/packages/hooks/src/useInfiniteScroll/index.tsx +++ b/packages/hooks/src/useInfiniteScroll/index.tsx @@ -99,10 +99,12 @@ const useInfiniteScroll = ( const scrollTop = getScrollTop(el); const scrollHeight = getScrollHeight(el); const clientHeight = getClientHeight(el); + const scrollBoundary = clientHeight + threshold; const isReachToBottom = scrollHeight - scrollTop <= scrollBoundary; const isReachToTop = scrollTop + scrollHeight <= scrollBoundary; const isReachBoundary = isInverse ? isReachToTop : isReachToBottom; + if (isReachBoundary) { loadMore(); } From 5af217e9eb210d308cedceeea7588d39a7c27a87 Mon Sep 17 00:00:00 2001 From: Rom Orlovich Date: Wed, 6 Sep 2023 23:16:19 +0300 Subject: [PATCH 6/6] feat(useInfiniteScroll): fix test scroll to top --- packages/hooks/src/useInfiniteScroll/__tests__/index.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/hooks/src/useInfiniteScroll/__tests__/index.test.ts b/packages/hooks/src/useInfiniteScroll/__tests__/index.test.ts index 2f2f82f414..f6cfb6699a 100644 --- a/packages/hooks/src/useInfiniteScroll/__tests__/index.test.ts +++ b/packages/hooks/src/useInfiniteScroll/__tests__/index.test.ts @@ -17,8 +17,6 @@ export async function mockRequest() { }; } -const targetEl = document.createElement('div'); - const setup = (service: Service, options?: InfiniteScrollOptions) => renderHook(() => useInfiniteScroll(service, options)); @@ -76,6 +74,7 @@ describe('useInfiniteScroll', () => { }); it('should auto load when scroll to bottom', async () => { + const targetEl = document.createElement('div'); const events = {}; const mockAddEventListener = jest .spyOn(targetEl, 'addEventListener') @@ -126,6 +125,7 @@ describe('useInfiniteScroll', () => { }); it('should auto load when scroll to top', async () => { + const targetEl = document.createElement('div'); const events = {}; const mockAddEventListener = jest .spyOn(targetEl, 'addEventListener')