Presence
enter and exit animate an element in and out of the document. exit keeps the element in the DOM until the animation settles, then removes it, and an enter that arrives while an element is leaving cancels the removal and carries on from where the element is, with its velocity.
Both always use the JS driver. In React, <Presence> wraps them for you.
Functions
Section titled “Functions”Jumps to the from values, then springs each of those properties to its identity value, or to the value in to when you give one.
export function enter( target: Element | readonly Element[], from: AnimationTargets, to: AnimationTargets = {}, options: EnterOptions = {},): AnimationControls| Parameter | Type | Default | Description |
|---|---|---|---|
target |
Element | readonly Element[] |
none | One element or an array. Each element of a list follows the rules on its own. |
from |
AnimationTargets |
none | Where the element starts. |
to |
AnimationTargets |
{} |
Overrides the identity value of a property. A property only to mentions animates from its current value. |
options |
EnterOptions |
{} |
Spring, scheduler and reduced motion. |
Returns AnimationControls.
Behavior
- Identity values are
0forx,y,rotateandblur, and1forscale,scaleX,scaleYandopacity. Properties that are not mentioned are never written. - An element that is already animating one of the goal properties, for example one that is exiting, is only retargeted: no jump to
from, position and velocity are kept. A single animating goal property is enough to retarget the whole element. The properties its exit animated also return to their identity unlesstosays otherwise. A compositor animation of the element counts as in flight. - It interrupts a running
exit()on the element: its removal is cancelled, theinertandaria-hiddenattributes it set are restored, and itsfinishedresolvesfalse. - Settled elements start from
fromagain. - Reduced motion. Spatial entries jump, so the transform lands on the identity on the first frame, while
opacityandblurstill animate. - The scheduler idles once every enter and exit has settled.
Edge cases
- Throws a
TypeErrororRangeErrorfor an unknown or non-finite property infromorto(labelsenter fromandenter to), and aRangeErrorfor invalid spring options, before any element is touched. - A failed
enterleaves a running exit alone.
Example
import { enter } from "@damped/core";
const toast = document.querySelector<HTMLElement>(".toast");
if (toast !== null) { // From invisible and 12 px low, to the identity values (opacity 1, y 0). await enter(toast, { opacity: 0, y: 12 }, {}, { duration: 0.3, bounce: 0 }).finished;}See also: exit, EnterOptions, Presence, Presence, Demos
Animates the element to the to values and then removes it, or hands it to your callback, unless something interrupts it first.
export function exit( target: Element | readonly Element[], to: AnimationTargets, options: ExitOptions = {},): { readonly finished: Promise<boolean>; stop(): void }| Parameter | Type | Default | Description |
|---|---|---|---|
target |
Element | readonly Element[] |
none | One element or an array. Each element is removed when its own animation settles. |
to |
AnimationTargets |
none | Where the element animates to. |
options |
ExitOptions |
{} |
Spring, scheduler, reduced motion, from and remove. |
Returns an object with finished: Promise<boolean> and stop(). finished resolves true after the removal or the callback, and false if the exit was interrupted. With several elements it is true only if every element completed.
Behavior
- While exiting, the element gets
inertandaria-hidden="true". The values it had are restored when the exit is interrupted, stopped, or finishes withremove: falseor a function. - When it settles without being interrupted,
removedecides:true(the default) callselement.remove(),falseleaves the element in place, and a function is called with the element instead. - Interruption.
finishedresolvesfalsewhen a laterenter(), a laterexit()on the element,stop()or a directanimate()that takes over one of its properties interrupts it. With a secondexit()only the second removes the element, and the first exit’sstop()no longer touches it. - Reduced motion. Spatial targets jump and
opacityanimates; the element is removed after the opacity settled. An exit with only spatial targets completes, and removes, at once. stop()freezes the exit, resolvesfinishedwithfalse, keeps the element and restores the attributes. It does nothing after the exit completed, and it stops every element of a list.optionsacceptsfrom(a jump),schedulerandreducedMotion, notdriver.
Edge cases
- A
removefunction that throws does not rejectfinished. The exit still counts as completed and the error is rethrown from a microtask. - An empty
toremoves the element on the next microtask, withfinishedalready resolved. - Throws before touching any element for invalid
toor spring options. removeis not validated.
The toast stack below enters and leaves with these functions (through <Presence>). Add and dismiss toasts quickly: a toast that comes back while it leaves reverses from where it is.
Enter and exit with Presence
- Payment sent to Jane Doe
- Bill paid: City Power
Example
import { exit } from "@damped/core";
const toast = document.querySelector<HTMLElement>(".toast");
if (toast !== null) { // To invisible, then removed from the DOM. `completed` is false if an enter() or another exit() interrupted it. const leaving = exit(toast, { opacity: 0, y: -12 }, { duration: 0.3, bounce: 0 }); const completed = await leaving.finished;
// Keep the element and handle it yourself. const banner = document.querySelector<HTMLElement>(".banner"); if (banner !== null) { void exit(banner, { opacity: 0 }, { remove: (element) => element.setAttribute("hidden", "") }); } console.log(completed);}See also: enter, ExitOptions, Presence, Presence, Reduced motion
EnterOptions
Section titled “EnterOptions”The options of enter: the spring, scheduler and reduced motion options of animate, without from and driver.
export type EnterOptions = DistributiveOmit<AnimateOptions, "from" | "driver">;| Option | Type | Default | Description |
|---|---|---|---|
| spring options | SpringOptions |
duration: 0.5, bounce: 0.15 |
Either form. |
scheduler |
Scheduler |
the shared frame |
Fixed per element by the first call. |
reducedMotion |
"user" | "always" | "never" |
"user" |
Spatial entries jump when it is on. |
Behavior
fromis removed becauseenteralready takes it as a required argument. Both spring option forms stay available.- It is also the type of the
optionsprop of<Presence>.
Example
import { enter, type EnterOptions } from "@damped/core";
const options: EnterOptions = { duration: 0.35, bounce: 0.1, reducedMotion: "user" };
const row = document.querySelector<HTMLElement>(".row");if (row !== null) { void enter(row, { opacity: 0, x: -16 }, {}, options);}See also: enter, ExitOptions, PresenceProps
ExitOptions
Section titled “ExitOptions”The options of exit: the options of animate without driver, plus remove.
export type ExitOptions = DistributiveOmit<AnimateOptions, "driver"> & { /** What to do once the exit settles without being interrupted: true (default) removes the element from the DOM; false leaves it; a function is called instead. */ remove?: boolean | ((element: Element) => void);};| Option | Type | Default | Description |
|---|---|---|---|
| spring options | SpringOptions |
duration: 0.5, bounce: 0.15 |
Either form. |
scheduler |
Scheduler |
the shared frame |
Fixed per element by the first call. |
reducedMotion |
"user" | "always" | "never" |
"user" |
Spatial targets jump when it is on. |
from |
AnimationTargets |
none | A jump applied before animating. |
remove |
boolean | ((element: Element) => void) |
true |
true removes the element once the exit settles, false leaves it (attributes restored), a function is called with the element instead (attributes restored). Not called when the exit is interrupted. |
Behavior
removeruns only when the exit settles without being interrupted.- With
remove: falseor a function, the element is left behind in the document with theinertandaria-hiddenvalues it had before the exit.
Example
import { exit, type ExitOptions } from "@damped/core";
// Hide instead of removing, so the element can come back later.const options: ExitOptions = { duration: 0.3, bounce: 0, remove: (element) => element.setAttribute("hidden", ""),};
const panel = document.querySelector<HTMLElement>(".panel");if (panel !== null) { void exit(panel, { opacity: 0, y: 8 }, options);}See also: exit, EnterOptions, PresenceProps