Presence

Contents

  1. Usage
  2. Props

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.

Did you know?

There's an incredible new set of developer tools for Chrome that let you inspect, edit and export Motion One and CSS animations.