Skip to content

AnimateAppear

A list of things settling into place one after another. Each child gets the same short fade and drift, held back by its position, so the effect belongs to the set rather than to any one item.

tsx
import { AnimateAppear } from 'neba';

<AnimateAppear className="flex flex-col gap-2">
  <Card title="Design review">Thursday, 14:00</Card>
  <Card title="Sprint planning">Friday, 10:00</Card>
</AnimateAppear>;

Props

PropTypeDefaultDescription
fromshared'top' | 'right' | 'bottom' | 'left''bottom'Which edge each child drifts in from
distancenumber | string'0.75rem'How far each child travels. Short on purpose: this is a settling, not an entrance from off screen
fadebooleantrueFades each child in as it settles
staggersharednumber80How long after one child the next one starts, in milliseconds. 0 animates the box itself; anything above it moves the effect onto each child in turn
durationStepsharednumber0How much longer each successive child takes, in milliseconds. Negative speeds them up down the list, and never past zero
reversesharedbooleanfalseRuns the children from the last to the first. Only the order reverses
durationsharednumber420How long one run takes, in milliseconds
delaysharednumber0How long before it starts, in milliseconds
easingstringThe easing curve, as CSS writes it. Defaults to the house curve
repeatsharednumber | 'infinite'1How many times it runs
alternatesharedbooleanfalseRuns every other pass backwards, so a repeat returns instead of jumping
triggershared'mount' | 'visible' | 'hover' | 'manual''mount'What starts it. visible is on scrolling into view, hover is under the pointer (focus counts), manual is whatever play says
playbooleanRuns it when trigger is manual. Each false → true starts it over
oncesharedbooleantrueWith trigger="visible", whether it runs only the first time. Off, it runs again on every return
thresholdsharednumber0.2With trigger="visible", how much of the element has to be on screen, from 0 to 1
pausedsharedbooleanfalseHolds the animation where it is
renderuseRender.RenderPropRenders something other than a div (render={<ul />}). Base UI's own escape hatch
childrenReactNodeThe things that appear, one after another. Each child is one step

Every other <div> attribute passes through to the root. The settings shared by every Animate* are defined in prop conventions.

The animation is written onto the children themselves rather than onto wrappers around them, so a row of <li>s stays a row of <li>s and a grid's cells stay its direct children. Only a bare string has no element to write onto; that one is wrapped in a <span>.

Examples

stagger

How long after one child the next one starts, in milliseconds. This is the whole effect: everything else is what a single child does.

The stagger is per child, which means what you pass matters: eight children are eight steps, and one child holding eight things is one step. That is also how to opt part of a list out: group it.

from, distance and reverse

from is the edge each child drifts in from and distance is how far: short on purpose, because this is a settling rather than an entrance from off screen. reverse runs the list from the last child to the first.

trigger="visible"

The natural pairing: a block of content that settles in as the reader reaches it, once. The whole set shares one observer on the root, so a list of forty is one observer rather than forty.

Accessibility

  • A reduced-motion preference switches the animation off entirely and the whole list is simply there.
  • The wrapper adds no role and no name. Give it a real element with render (render={<ul />}) when the list is a list.

Released under the MIT License