Perform exit animations in Solid with Presence and Show.
<Presence> <Show when={toggle()}> <Motion animate={{ opacity: 1 }} exit={{ opacity: 0 }} /> </Show> </Presence>
Usage
Import Motion
from "@motionone/solid"
and register it with your component.
import { Component, createSignal, Show } from "solid-js"; import { Motion, Presence } from "@motionone/solid"; const App: Component = () => { const [toggle, setToggle] = createSignal(true); return ( <div class="container"> <Presence exitBeforeEnter> <Show when={toggle()}> <Motion.div initial={{ opacity: 0, scale: 0.6 }} animate={{ opacity: 1, scale: 1 }} exit={{ opacity: 0, scale: 0.6 }} transition={{ duration: 0.3 }} /> </Show> </Presence> <button onClick={() => setToggle(!toggle())}> Toggle </button> </div> ); }; export default App;
Now, when a child Motion
component is hidden with <Show>
, it will animate to the target defined in exit
prop.
Note: Presence
currently only supports a single rendered child.
Animate between elements
By passing a different key
to multiple children and rendering just one at a time, we can animate between them at a given time.
import { Component, createSignal } from "solid-js"; import { Motion, Presence } from "@motionone/solid"; import { Rerun } from "@solid-primitives/keyed"; const App: Component = () => { const [count, setCount] = createSignal(1); const increment = () => setCount((p) => ++p); return <> <Presence exitBeforeEnter> <Rerun on={count()}> <Motion initial={{ opacity: 0, x: 50 }} animate={{ opacity: 1, x: 0, transition: { delay: 0.05 } }} transition={{ duration: 0.1 }} exit={{ opacity: 0, x: -50 }} > {count()} </Motion> </Rerun> </Presence> <button onClick={increment}>Next</button> </>; }; export default App;
In the above example, each element has the position: absolute
CSS rule so when the incoming element is rendered it doesn't conflict with the element animating away.
In situations where this isn't possible, exitBeforeEnter={true}
can be set on Presence
to ensure the exiting element animates out before the entering element is rendered.
Props
initial
Default: true
If false
, will disable the first animation on all child Motion
elements the first time Presence
is rendered.
exitBeforeEnter
Default: false
If true
, Presence
will wait for the exiting element to finish animating out before animating in the next one.