feat(design-system): add infiniteScroll to DsTable to handle scroll pagination [AR-62554]#465
Merged
iromanchuk-dn merged 7 commits intoMay 13, 2026
Conversation
…it handle scroll and auto-fill pagination [AR-62554]
✅ Deploy Preview for drivenets-design-system ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
infiniteScroll prop to DsTable, letting it handle scroll and auto-fill pagination [AR-62554]infiniteScroll to DsTableto handle scroll and auto-fill pagination [AR-62554]
infiniteScroll to DsTableto handle scroll and auto-fill pagination [AR-62554]infiniteScroll to DsTableto handle scroll pagination [AR-62554]
infiniteScroll to DsTableto handle scroll pagination [AR-62554]infiniteScroll to DsTable to handle scroll pagination [AR-62554]
mmurawski-dn
previously approved these changes
May 12, 2026
| expect(onLoadMore).not.toHaveBeenCalled(); | ||
| }); | ||
|
|
||
| it('latch: rapid scroll events before isLoadingMore propagates fire onLoadMore at most once', async () => { |
Collaborator
There was a problem hiding this comment.
Tests cover “rapid scroll before loading flag propagates”, but there’s no test for the valid API case where onLoadMore is sync (or async without isLoadingMore) and should still allow repeated pagination cycles.
Collaborator
Author
There was a problem hiding this comment.
I removed latch behavior, it's overcomplicates things.
mmurawski-dn
previously approved these changes
May 13, 2026
mmurawski-dn
approved these changes
May 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Consumers of the virtualized
DsTablehad to hand-roll infinite scroll on every page:onScroll, computebottomOffset, compare to a threshold, gate onisFetching/hasMore.useEffecton mount and after each fetch to handle the "initial data is shorter than the viewport, so no scrollbar ever appears" footgun. It is not possible today and a related bug was reported.Solution
Encapsulate viewport/scroll detection inside
DsTable. Consumers keep ownership of fetching, pagination state, and retry; the Table owns when to ask for more.New prop
infiniteScroll= feature on. Noenabledflag.hasMore: falseis the runtime off-switch (end of data, error, pause).autoFill: truekeeps requesting pages until the viewport is actually scrollable — fixes the "short first page" footgun by default.onLoadMoreaccepts(() => void) | (() => Promise<unknown>), so React Query'sfetchNextPagecan be passed directly without a wrapper.onScrollprop continues to work independently for analytics / scroll indicators.Implementation
useInfiniteScrollhook (use-infinite-scroll.ts) owns threshold detection, the auto-fill loop, and an in-flight latch.onLoadMorefires; cleared whenisLoadingMoretransitions totrue. Closes the 1–2 frame gap before the consumer's loading flag propagates without forcingPromisesemantics on the API.onChangefor scroll-driven triggers and auseEffectonrows.lengthfor mount / data-append / auto-fill. TheisNearBottomcheck is gated on actual scrollability so it doesn't false-fire when content is shorter than the viewport.Migration & coverage
VirtualizedSelectableandVirtualizedExpandablestories migrated off the manualfetchMoreOnBottomReached+getScrollPositionplumbing.InfiniteScroll(5-row initial page) stories anchor the API.ds-table-infinite-scroll.browser.test.tsxcovers: threshold trigger,hasMore: falseguard,isLoadingMore: trueguard, auto-fill on mount (bothtrueandfalse), and the latch regression.Test plan
pnpm eslint packages/design-system/src/components/ds-table/pnpm --filter @drivenets/design-system typecheckpnpm --filter @drivenets/design-system test src/components/ds-table/__tests__/ --run