AnimateBlink
Content pulsing between full opacity and a floor. The cycle is symmetric, so however many times it runs it ends where it started.
import { AnimateBlink } from 'neba';
<AnimateBlink min={0.35}>
<Chip color="danger" variant="solid">
Recording
</Chip>
</AnimateBlink>;Props
| Prop | Type | Default | Description |
|---|---|---|---|
| min | number | 0 | How faint it gets at the bottom of the cycle, between 0 and 1 |
| 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 |
| durationshared | number | 900 | 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' | 'infinite' | 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={<span />}). Base UI's own escape hatch |
| children | ReactNode | — | What pulses |
Every other <div> attribute passes through to the root. The settings shared by every Animate* are defined in prop conventions.
There is no mode: the cycle is the same in both directions, so there is nothing for a reversed one to mean.
Examples
min
How faint it gets at the bottom of the cycle, between 0 and 1. At 0 the content disappears; raise it for anything that has to stay readable while it pulses, which is most things.
repeat
It repeats forever unless told otherwise, because a single blink is a flicker rather than an effect. A count is for drawing attention once: three pulses and then still.
paused
paused holds the animation where it is, which is how to stop a live indicator without unmounting it.
<AnimateBlink paused={!recording} min={0.35}>
<Chip color="danger">Recording</Chip>
</AnimateBlink>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 sits at full opacity.
- Because of that, the blink is never the only thing carrying the message. Say it in words too: a
Chipthat reads "Recording" says it whether or not it is pulsing. - Something that never stops moving in the corner of a page being read is the one kind of motion this library otherwise refuses. Use it for a state that is genuinely live, and stop it when the state ends.