Infinite Scroll Footer
A footer spinner fills a slot that was already reserved, and the next page fades in above it.
The animated component in this preview is rendered from the canonical file shown here. The surrounding demo shell only provides context and is not part of the copied code.
import { useCallback, useEffect, useRef, useState } from "react";
import { AnimatePresence, motion, useReducedMotion } from "motion/react";
/**
* Vibary · Infinite Scroll Footer
*
* The footer is the whole contract: a sentinel at the end of the list
* asks for the next page, a spinner sits in a slot that is alreadyAbout this pattern
Pagination that never interrupts reading. A sentinel at the end of the list asks for the next page as it comes into view, the footer slot fills with a turning arc, and the arriving rows fade and lift into place a few tens of milliseconds apart so the eye can see where the list grew. The slot is a fixed height whether it holds a spinner, an end-of-results note or nothing at all — that constant is the whole trick, because a footer that grows and collapses drags the rows above it up and down and costs the reader their place. The spinner also resolves the ambiguity a bare list can't: the difference between more results coming and no more results existing.
Where it shows up
Screens we drew to show where this motion usually sits. Illustrations, not captures of any product.
- Photo gallery
Reaching the end of the grid quietly requests the following page and the new items settle in above the footer.
Related patterns
- Background Refresh HintA two-pixel tinted band travels the panel's top edge while data refetches, without interrupting reading.
- Content Placeholder PulsePlaceholder blocks rise and fall together on one slow cadence, so the region reads as dormant rather than busy.
- Lazy Section RevealA below-the-fold section fades and lifts the first time it comes into view, and never again after that.
