Skip to content

Transitions

CSS-based enter/leave animations using snabbdom hooks. Sygnal uses a Vue-style transition system where a single name prop generates six CSS classes for fine-grained control over enter and leave animations.

import { Transition } from 'sygnal'
function AnimatedList({ state }) {
return (
<div>
<Transition name="fade">
{state.visible && <div className="content">Animated!</div>}
</Transition>
</div>
)
}
PropTypeDefaultDescription
namestring'v'Base name for generated CSS classes
durationnumberExplicit timeout in ms. If omitted, listens for transitionend event

Given name="fade", the following classes are applied automatically:

On enter (element inserted):

  1. fade-enter-from + fade-enter-active added simultaneously
  2. Next frame: fade-enter-from removed, fade-enter-to added
  3. On transition end: fade-enter-active and fade-enter-to removed

On leave (element removed):

  1. fade-leave-from + fade-leave-active added simultaneously
  2. Next frame: fade-leave-from removed, fade-leave-to added
  3. On transition end: fade-leave-active and fade-leave-to removed, then element is removed from DOM
/* Active classes define the transition properties */
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s ease;
}
/* "from" classes define the starting state */
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
.slide-enter-active,
.slide-leave-active {
transition: transform 0.3s ease;
}
.slide-enter-from {
transform: translateX(-100%);
}
.slide-leave-to {
transform: translateX(100%);
}
<Transition name="slide">
{state.showPanel && <div className="panel">Slides in and out</div>}
</Transition>

If your animation doesn’t use CSS transitions (or you want a fixed timeout), pass duration:

<Transition name="fade" duration={500}>
{state.visible && <div>Uses setTimeout instead of transitionend</div>}
</Transition>