AnimateSlide
Content travelling in from one edge. The default distance is the element's own size, so it starts exactly out of frame and is never half drawn somewhere it does not belong.
import { AnimateSlide } from 'neba';
<div className="overflow-hidden">
<AnimateSlide from="left">
<Alert color="success" title="Invitation sent" />
</AnimateSlide>
</div>;Props
| Prop | Type | Default | Description |
|---|---|---|---|
| fromshared | 'top' | 'right' | 'bottom' | 'left' | 'bottom' | Which edge it travels from. Physical, as NebaSide is everywhere |
| distance | number | string | '100%' | How far it travels: a CSS length, or a number in pixels. '100%' is the element's own size |
| fade | boolean | true | Fades in as it slides |
| staggershared | number | 0 | How 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 |
| durationStepshared | number | 0 | How much longer each successive child takes, in milliseconds. Negative speeds them up down the list, and never past zero |
| reverseshared | boolean | false | Runs the children from the last to the first. Only the order reverses |
| modeshared | 'in' | 'out' | 'in' | Whether the content arrives or leaves. out is the same animation run backwards, and it is held there |
| durationshared | number | 380 | How long one run takes, in milliseconds |
| delayshared | number | 0 | How long before it starts, in milliseconds |
| easing | string | — | The easing curve, as CSS writes it. Defaults to the house curve |
| repeatshared | number | 'infinite' | 1 | How many times it runs |
| alternateshared | boolean | false | Runs 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 |
| play | boolean | — | Runs it when trigger is manual. Each false → true starts it over |
| onceshared | boolean | true | With trigger="visible", whether it runs only the first time. Off, it runs again on every return |
| thresholdshared | number | 0.2 | With trigger="visible", how much of the element has to be on screen, from 0 to 1 |
| pausedshared | boolean | false | Holds the animation where it is |
| render | useRender.RenderProp | — | Renders something other than a div (render={<aside />}). Base UI's own escape hatch |
| children | ReactNode | — | What travels in |
Every other <div> attribute passes through to the root. The settings shared by every Animate* are defined in prop conventions.
Examples
from
Which edge it travels from: top, right, bottom or left. Physical rather than logical, as NebaSide is everywhere in the library: a panel sliding down from the top comes from the top in every writing direction.
Put it in a box with overflow: hidden and the effect is a panel appearing from behind that box's edge.
import { useState } from 'react';
import { AnimateSlide, Box, Button, Typography } from 'neba';
const EDGES = ['top', 'right', 'bottom', 'left'] as const;
export default function AnimateSlideEdges() {
const [run, setRun] = useState(0);
return (
<div className="flex flex-col items-center gap-4">
<Button size="sm" variant="outline" onClick={() => setRun((count) => count + 1)}>
Play again
</Button>
<div className="flex flex-wrap items-center justify-center gap-3">
{EDGES.map((edge) => (
<div key={edge} className="overflow-hidden">
<AnimateSlide key={`${edge}-${run}`} from={edge} duration={700}>
<Box size="sm">
<Typography level="caption">from {edge}</Typography>
</Box>
</AnimateSlide>
</div>
))}
</div>
</div>
);
}distance
A CSS length or a number in pixels. '100%' (the default) is the element's own width or height. A short distance is a nudge rather than an entrance; for a whole list of those, one after another, use AnimateAppear.
import { AnimateSlide, Chip } from 'neba';
/* A short distance is a nudge; the default is the element's own size, which
starts it exactly out of frame. */
export default function AnimateSlideDistance() {
return (
<div className="flex items-center gap-3">
<AnimateSlide distance={8} duration={1200} repeat="infinite" alternate fade={false}>
<Chip>8px</Chip>
</AnimateSlide>
<AnimateSlide distance="4rem" duration={1200} repeat="infinite" alternate>
<Chip color="info">4rem</Chip>
</AnimateSlide>
</div>
);
}mode
out sends it back the way it came, held off screen at the end.
<AnimateSlide mode="out" from="right">
<Toolbar>…</Toolbar>
</AnimateSlide>stagger
stagger, durationStep and reverse hand the effect to the children one at a time instead of running it on the box. They work the same way here as on AnimateFade, where they are set out in full.
Accessibility
- A reduced-motion preference switches the animation off entirely and the content is simply there, in place.
- The element is moved with
translate, so nothing on the page reflows while it runs and no layout under it changes.