dj-transition / dj-remove — declarative animations

Phoenix JS.transition parity. Apply a class for the duration of a state change. The framework handles the timing.

Tasks

dj-transition-group
Wire up the WebSocket consumer
Style the dashboard
Read the @action docs

The whole pattern

dj-transition-group="ENTER | LEAVE" wires dj-transition onto each new child and dj-remove onto every child for exit. The framework cycles classes and waits for transitionend automatically — no JS needed in your view.

{# pipe-separated short form: ENTER | LEAVE #}
<ul dj-transition-group="fade-in | fade-out">
    {% for task in tasks %}
        <li class="task">
            {{ task.title }}
            <button dj-click="remove" dj-value-id:int="{{ task.id }}">×</button>
        </li>
    {% endfor %}
</ul>

/* CSS — single-class transitionend-driven animations */
.fade-in  { animation: t-fade-in 300ms ease both; }
.fade-out { opacity: 0; transition: opacity 300ms ease; }

Compare to React's <TransitionGroup> / <CSSTransition> from react-transition-group — three packages, build-time install, runtime overhead. Here it's an HTML attribute.