Stagger List

Animated

A list whose items arrive one after another.

View Source

#Installation

npx @dinachi/cli@latest add stagger-list

#Usage

tsx
import { StaggerList, StaggerListItem } from "@/components/ui/stagger-list"
tsx
<StaggerList>
  {items.map((item) => (
    <StaggerListItem key={item.id}>{item.label}</StaggerListItem>
  ))}
</StaggerList>

#Examples

#Variants

VariantBehaviourUse it when
riseItems lift into place from below.Anything read top to bottom: the motion runs along the reading direction.
scaleItems settle in place from slightly small.Grids and card walls, where there is no single reading direction for a rise to follow.
blurItems pull into focus as they rise.Sparingly. The only variant that animates a filter, so the only one whose cost grows with the item count.

#When to use it

The sequence says the items arrived together and in an order, which is information a simultaneous fade does not carry.

Use it forNot for
A list the reader is seeing for the first time: search results landing, a dashboard's first paint, a feed's first page.A list that re-renders on every keystroke.
Content that arrives.Content the reader is scrolling back to. Re-running an entrance on what is already on screen is the fastest way to make a list feel slow.

#Behaviour

  • blur leaves a filter: blur(0px) on each item after it lands, which makes that item a containing block for any fixed-position descendant. Reach for rise or scale if the items contain one.
  • startOnView triggers on a root margin, not a visible fraction. A fraction of a tall list is a lot of scrolling, so a grid would sit at zero opacity while its first rows were already on screen.
  • One duration for every variant. A list entrance is UI, and UI motion stays under 300ms whichever channel it animates.

#Accessibility

  • The list keeps its ul/li semantics. Only the markers are dropped.
  • Reduced motion keeps the fade and the stagger, dropping only the second channel. Sequencing is not movement, and the sequence is the information this component carries.
  • StaggerListItem throws outside a StaggerList, since it has no sequence to belong to.

#API Reference

PropTypeDefaultDescription
variant"rise" | "scale" | "blur""rise"How each item enters
staggernumber0.05Seconds between each item. Keep it in the 0.03–0.08 range
delaynumber0Seconds before the first item
durationnumber0.3Seconds for each item's own animation
distancenumber8Item travel distance in px. Ignored by scale, which does not travel
startOnViewbooleantrueStart when scrolled into view rather than on mount