Tony Messias

December 7, 2023

FormKit's AutoAnimate With Stimulus

I saw FormKit's AutoAnimate lib on Laracasts and had to try it in a Hotwired app. Here's a quick one on how you can use it in your apps too.

Installing AutoAnimate

First, you need to pull it, I'm using Importmap Laravel so I can pull it using the `pin` command:

php artisan importmap:pin @formkit/auto-animate

This adds a new entry to the `routes/importmap.php` file:

<?php

use Tonysm\ImportmapLaravel\Facades\Importmap;

Importmap::pinAllFrom('resources/js', to: 'js/');

// ...

Importmap::pin(
  "@formkit/auto-animate",
  to: "https://ga.jspm.io/npm:@formkit/auto-animate@0.8.1/index.mjs",
);

Now, we can use it.

Using AutoAnimate

To use it, we can create a Stimulus controller. I'm using Stimulus Laravel, so I can create a new Stimulus controller using the `stimulus:make` command:

php artisan stimulus:make auto_animate

This should create a new file under `resources/js/controllers/auto_animate_controller.js` and automatically register the controller for us (I mean, if you're still using Vite. I'm using Importmap Laravel, so I don't have to worry about that as controllers are lazy-loaded as they appear in the DOM, but you could also eager-load them if you want to):

import { Controller } from "@hotwired/stimulus"
import autoAnimate from "@formkit/auto-animate"

// Connects to data-controller="auto-animate"
export default class extends Controller {
    connect() {
        autoAnimate(this.element)
    }
}

Now, we can add this controller to DOM elements when we want to automatically animate them as we append, prepend, or remove elements from them with `data-controller="auto-animate"`. For instance, in this example I have a chat system where new messages are simply being appended to the DOM, so I can add it to the element wrapping the messages:

<x-app-layout>
    <x-slot name="head">
        <x-turbo-refreshes-with
            method="morph"
            scroll="preserve" />
    </x-slot>

    <x-slot name="header">
        <!-- ... -->
    </x-slot>

    <div class="...">
        <div class="...">
            <div
                id="@domid($chat, 'messages')"
                data-controller="auto-animate"
            >
                @foreach ($chat->messages as $message)
                    @include('messages.partials.message', [
                        'message' => $message,
                    ])
                @endforeach
            </div>

            <!-- ... -->
        </div>
    </div>
</x-app-layout>

That's it! Here's a video of this at work. You can see the commit of where I added this to an example app. Check out the examples section on their docs.

About Tony Messias