Enter/Exit Animation

Motion applied as elements appear or leave.

Toast notification

Saved successfully.

entering · fade-slide · replays each time the panel re-renders

html

<div class="mot-eea-stage" data-state="entering" data-style="fade-slide">
  <div class="mot-eea-card" style="border-color:#F5C2E0;">
    <strong>Toast notification</strong>
    <p>Saved successfully.</p>
  </div>
  <p class="mot-eea-caption">entering &middot; fade-slide &middot; replays each time the panel re-renders</p>
</div>
<style>
.mot-eea-stage { width: 100%; max-width: 320px; min-height: 130px; padding: 16px; background: #FAF7F2; border: 1px solid #24143022; border-radius: 12px; font: 13px system-ui, sans-serif; color: #241430aa; }
.mot-eea-card { background: #fff; border: 2px solid; border-radius: 10px; padding: 12px 14px; color: #241430; font-size: 14px; }
.mot-eea-caption { margin: 10px 0 0; }
@media (prefers-reduced-motion: no-preference) {
  [data-state="entering"][data-style="fade-slide"] .mot-eea-card { animation: mot-eea-enter-slide 500ms ease-out both; }
  [data-state="exiting"][data-style="fade-slide"] .mot-eea-card { animation: mot-eea-exit-slide 500ms ease-in both; }
  [data-state="entering"][data-style="scale"] .mot-eea-card { animation: mot-eea-enter-scale 500ms ease-out both; }
  [data-state="exiting"][data-style="scale"] .mot-eea-card { animation: mot-eea-exit-scale 500ms ease-in both; }
  @keyframes mot-eea-enter-slide { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } }
  @keyframes mot-eea-exit-slide { from { opacity: 1; transform: translateY(0); } to { opacity: 0; transform: translateY(14px); } }
  @keyframes mot-eea-enter-scale { from { opacity: 0; transform: scale(.85); } to { opacity: 1; transform: scale(1); } }
  @keyframes mot-eea-exit-scale { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(.85); } }
}
</style>

tailwind

<div class="w-full max-w-[320px] min-h-[130px] p-4 bg-[#FAF7F2] border border-[#24143022] rounded-xl font-sans text-sm text-[#241430]/70" data-state="entering" data-style="fade-slide">
  <div class="bg-white border-2 rounded-lg px-3.5 py-3 text-[#241430] text-sm" style="border-color:#F5C2E0;">
    <strong>Toast notification</strong>
    <p>Saved successfully.</p>
  </div>
  <p class="mt-2.5">entering &middot; fade-slide &middot; replays each time the panel re-renders</p>
</div>
<style>
@media (prefers-reduced-motion: no-preference) {
  [data-state="entering"][data-style="fade-slide"] div > div { animation: mot-eea-tw-enter-slide 500ms ease-out both; }
  [data-state="exiting"][data-style="fade-slide"] div > div { animation: mot-eea-tw-exit-slide 500ms ease-in both; }
  [data-state="entering"][data-style="scale"] div > div { animation: mot-eea-tw-enter-scale 500ms ease-out both; }
  [data-state="exiting"][data-style="scale"] div > div { animation: mot-eea-tw-exit-scale 500ms ease-in both; }
  @keyframes mot-eea-tw-enter-slide { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } }
  @keyframes mot-eea-tw-exit-slide { from { opacity: 1; transform: translateY(0); } to { opacity: 0; transform: translateY(14px); } }
  @keyframes mot-eea-tw-enter-scale { from { opacity: 0; transform: scale(.85); } to { opacity: 1; transform: scale(1); } }
  @keyframes mot-eea-tw-exit-scale { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(.85); } }
}
</style>

react

export function EnterExitAnimation({
  state = "entering",
  style = "fade-slide",
  duration = 500,
  accent = "#F5C2E0",
}) {
  const anims = {
    "entering-fade-slide": "mot-eea-enter-slide",
    "exiting-fade-slide": "mot-eea-exit-slide",
    "entering-scale": "mot-eea-enter-scale",
    "exiting-scale": "mot-eea-exit-scale",
  };
  const name = anims[`${state}-${style}`];
  return (
    <div style={{ width: "100%", maxWidth: 320, minHeight: 130, padding: 16, background: "#FAF7F2", border: "1px solid #24143022", borderRadius: 12, fontFamily: "system-ui, sans-serif", fontSize: 13, color: "#241430aa" }}>
      <div className="card" style={{ background: "#fff", border: `2px solid ${accent}`, borderRadius: 10, padding: "12px 14px", color: "#241430", fontSize: 14 }}>
        <strong>Toast notification</strong>
        <p>Saved successfully.</p>
      </div>
      <p style={{ margin: "10px 0 0" }}>{state} &middot; {style} &middot; replays each time the panel re-renders</p>
      <style>{`
        @media (prefers-reduced-motion: no-preference) {
          .card { animation: ${name} ${duration}ms ${state === "entering" ? "ease-out" : "ease-in"} both; }
          @keyframes mot-eea-enter-slide { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } }
          @keyframes mot-eea-exit-slide { from { opacity: 1; transform: translateY(0); } to { opacity: 0; transform: translateY(14px); } }
          @keyframes mot-eea-enter-scale { from { opacity: 0; transform: scale(.85); } to { opacity: 1; transform: scale(1); } }
          @keyframes mot-eea-exit-scale { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(.85); } }
        }
      `}</style>
    </div>
  );
}