Skip to content

Latest commit

 

History

History
414 lines (324 loc) · 16.2 KB

id_README.md

File metadata and controls

414 lines (324 loc) · 16.2 KB

alpinejs-flux

English | Indonesia

Codepen Demo

Menyederhanakan proses penerapan kelas-kelas CSS di x-transition dengan membuat template yang dapat digunakan berulang kali dalam satu direktif.

Diperlukan alpinejs v3.11.0 atau lebih tinggi.

Demo

Perancangan

Isi Perancangan Catatan: Dokumentasi API ada di paling bawah.

Singkat apa itu API directive dan magic di alpinejs:

  • Directive adalah sebuah API dalam bentuk atribut yang biasa digunakan untuk memanipulasi elemen HTML yang dituju.
  • Magic adalah sebuah API properti atau method yang kapan saja dapat kita panggil hampir di semua tempat di dalam lingkungan alpinejs serta mereferensikan sumber elemen.

Sebuah plugin alpinejs akan terinisiasi secara otomatis apabila kamu menggunakan CDN atau jalur inline script. Jika kamu menggunakan package manager seperti yarn atau npm, maka kamu perlu menginisiasi plugin tersebut secara manual sebagaimana contoh dibawah nanti.

AlpineJS Flux, plugin ini merupakan sebuah pembungkus satu directive yang akan menerapkan semua directive x-transition secara otomatis. Apabila kamu tidak menggunakan kelas-kelas CSS atau hanya ingin menggunakan transisi opacity dan scale maka kamu tidak perlu menggunakan plugin ini karena secara bawaan x-transition sudah menyediakan mekanisme tersebut.

Dalam perancangan awal, saya hanya terpikirkan untuk membuat satu directive saja dengan array sebagai isinya:

<div
    x-show="show"
    x-flux="[
        'transition duration-300', // transition untuk masuk dan keluar
        'opacity-0 scale-90', // transisi pangkal ketika masuk dan ujung ketika keluar
        'opacity-100 scale-100', // transisi ujung ketika masuk dan pangkal ketika keluar
        'ease-out', 'ease-in' // transisi ketika masuk, transisi ketika keluar (perhatikan koma)
    ]"
>Ekspresi Array</div>

Setelah pembuatan dan pengetesan, saya terpikirkan kalau ini apa bedanya dengan x-transition itu sendiri, masih sama saja menyalin dan tempel berulang kali dan terlebih lagi kalau ada elemen yang tipe transisi masuk/keluarnya berbeda misalnya ketika masuk elemennya berputar (rotate) dan ketika keluar perlahan menghilang (fade out), saya nantinya harus kembali menggunakan x-transition lagi yang ingin saya hindari. Jadi saya memutuskan untuk membuat sebuah konfigurasi global untuk menyimpan nilai-nilai transisi sebagai template yang dapat digunakan kembali di berbagai elemen hanya dengan mereferensikan nama template tersebut.

Kita bisa mendefinisikan sebuah template transisi ketika akan menginisialisasi plugin ini:

import Alpine from 'alpinejs'
import Flux from 'alpinejs-flux'

Alpine.plugin(() => {
    Flux(Alpine, {
        "translate-y-2": [
            "transition duration-300", // transition
            "opacity-0 scale-90 translate-y-2", // enter-start | leave-end
            "opacity-100 scale-100 translate-y-0", // enter-end | leave-start
            "ease-out", "ease-in" // enter, leave
        ],
        rotate: {
            "enter": "transition-all ease-in-out transform duration-300",
            "enter-start": "opacity-0 scale-90",
            "enter-end": "opacity-100 scale-100 rotate-180",
            "leave": "transition-all ease-in-out transform duration-300",
            "leave-start": "opacity-100 scale-100",
            "leave-end": "opacity-0 scale-90"
        }
    });
});

Alpine.start()

Dan terbitlah versi pertama plugin ini,

Lihat kode v1.0.0

Sedikit beda dengan cara inisiasi plugin alpinejs lain pada umumnya, hal ini diperlukan ketika kita ingin meneruskan suatu argumen ke dalam plugin.

Nama template di konfigurasi menggunakan aturan kebab-case dan tipe data objek daripada map karena untuk penyimpanan skala kecil, map tidak akan memberikan keuntungan apapun.

Saya mendapat masukkan dari salah satu kontributor di alpinejs bahwasanya akan lebih praktis bila kita bisa menggunakan magic daripada directive x-flux. Saya setuju dengan masukannya dan menambahkan magic untuk menerapkan template yang sudah didefinisikan di konfigurasi. Magic didaftarkan secara dinamis dengan nama template yang terdefinisikan dengan aturan camelCase.

<!-- Kamu bisa memanggil template yang sudah didefinisikan di konfigurasi -->
<div x-show="show" x-flux="'translate-y-2'">Array dari Konfigurasi</div>

<!-- Atau kamu bisa gunakan magic -->
<div x-show="show" x-init="$translateY2">Array dari Konfigurasi</div>
<div x-show="show" x-init="$flux('translate-y-2')">Array dari Konfigurasi</div>

Lihat kode v1.1.0 | Atau komparasi perubahan v1.0.0 > v1.1.0

Saya menyarankan untuk memakai x-flux apabila elemen yang di tuju sudah memiliki x-init demi kemudahan dalam membaca, dan juga saya rasa magic ini akan lebih cocok untuk digunakan pada elemen yang belum memiliki x-init atau terutama berada di dalam method init pada Alpine.data().

Alpine.data('tooltip', () => ({
    show: false,
    init() {
        this.$translateY2(); // pilih salah satu
        this.$flux('translate-y-2'); // pilih salah satu
    },
    // ...
}));

Lalu bagaimana cara kita memasukkan template baru apabila kita menggunakan CDN script daripada bundle module, cara sebelumnya tentunya tidak bisa di terapkan karena memang keterbatasan apabila kita menggunakan CDN script. Untuk itu saya menambahkan magic $flux yang dapat digunakan untuk menerapkan atau membuat template baru secara dinamis.

<section
    x-data="{ template: [
        'transition duration-300',
        'opacity-0 scale-90',
        'opacity-100 scale-100',
        'ease-out', 'ease-in',
    ] }"
>
    <!-- Kamu bisa membuat template melalui magic flux, aturan nama template harus kebab-case -->
    <div x-show="show" x-init="$flux('opacity-scale', template)">Ekspresi Array</div>

    <!-- Secara bawaan template yang dibuat akan otomatis di terapkan pada elemen, kamu bisa menonaktifkan ini dengan memberikan nilai false pada parameter ketiga -->
    <div x-show="show" x-init="$flux('opacity-scale', template, false)">Ekspresi Array</div>

    <!-- Kamu juga bisa membuat template dengan cara mengirimkan array/objek langsung -->
    <div x-show="show" x-init="$flux('opacity-scale', [
        'transition duration-300',
        'opacity-0 scale-90',
        'opacity-100 scale-100',
        'ease-out', 'ease-in',
    ])">Ekspresi Array</div>
</section>

Saya baru kepikiran membuatkannya dengan patch v1.2.0 karena saya hampir tidak pernah menulis CDN/inline script.

Lihat kode v1.2.0 | Atau komparasi perubahan v1.1.0 > v1.2.0

Lalu saya akhiri dengan perubahan terakhir v1.2.1 dan v1.2.2 untuk membuat variable assigments di dalam directive x-flux dan kode menjadi lebih rapi dan mudah dibaca.

Cek komparasi perubahan v1.2.0 > v1.2.1 Cek komparasi perubahan v1.2.1 > v1.2.2

Apa selanjutnya? saya terpikirkan untuk menyederhanakan cara mendefinisikan template lewat objek karena penulisannya mirip dengan si x-transition itu sendiri, untuk sekarang seperti ini:

{
    "enter": "transition-all ease-in-out transform duration-300",
    "enter-start": "opacity-0 scale-90",
    "enter-end": "opacity-100 scale-100 rotate-180",
    "leave": "transition-all ease-in-out transform duration-300",
    "leave-start": "opacity-100 scale-100",
    "leave-end": "opacity-0 scale-90"
}

Mungkin akan saya buat menjadi seperti ini:

{
    "transition": "transition-all ease-in-out transform duration-300",
    "enter": [
        "opacity-0 scale-90",
        "opacity-100 scale-100 rotate-180"
    ],
    "leave": [
        "opacity-100 scale-100",
        "opacity-0 scale-90"
    ]
}

Itu masih berupa ide, saya masih belum pasti apakah akan saya terapkan atau tidak.

Install

Dengan CDN

<script defer src="https://unpkg.com/alpinejs-flux@latest/dist/flux.min.js"></script>

<script defer src="https://unpkg.com/[email protected]/dist/cdn.min.js"></script>

Dengan Package Manager

yarn add -D alpinejs-flux

npm install -D alpinejs-flux
import Alpine from 'alpinejs'
import Flux from 'alpinejs-flux'

Alpine.plugin(() => {
    Flux(Alpine, {
        "translate-y-2": [
            "transition duration-300", // transition
            "opacity-0 scale-90 translate-y-2", // enter-start | leave-end
            "opacity-100 scale-100 translate-y-0", // enter-end | leave-start
            "ease-out", "ease-in" // enter, leave
        ],
        rotate: {
            "enter": "transition-all ease-in-out transform duration-300",
            "enter-start": "opacity-0 scale-90",
            "enter-end": "opacity-100 scale-100 rotate-180",
            "leave": "transition-all ease-in-out transform duration-300",
            "leave-start": "opacity-100 scale-100",
            "leave-end": "opacity-0 scale-90"
        }
    });
});

Alpine.start()

Penggunaan

Ada beberapa cara untuk menggunakan plugin ini.

1. Membuat template secara inline

Panduan cara membuat template secara inline dan di terapkan pada elemen secara otomatis saat elemen tersebut di render.

<section x-data="{ show: false }">
    <button @click="show = !show">Toggle</button>

    <!-- Kamu bisa membuat anonymous template secara inline dengan directive x-flux -->
    <div x-show="show" x-flux="[
        'transition duration-300',
        'opacity-0 scale-90',
        'opacity-100 scale-100',
        'ease-out', 'ease-in',
    ]">Anonymous Template</div>

    <!-- Atau kamu juga bisa membuat anonymous template secara inline dengan magic $flux -->
    <div x-show="show" x-init="$flux('', [
        'transition duration-300',
        'opacity-0 scale-90',
        'opacity-100 scale-100',
        'ease-out', 'ease-in',
    ])">Anonymous Template</div>

    <!-- (Masih Belum Di rilis ke npm! Jangan digunakan) Atau kamu juga bisa membuat anonymous template secara inline dengan magic $flux -->
    <div x-show="show" x-init="$flux([
        'transition duration-300',
        'opacity-0 scale-90',
        'opacity-100 scale-100',
        'ease-out', 'ease-in',
    ])">Anonymous Template</div>
</section>

2. Membuat template di dalam x-data

Panduan cara membuat template di dalam x-data dan memanggilnya dengan directive x-flux dan magic $flux.

<section x-data="{ show: false, template: [
        'transition duration-300',
        'opacity-0 scale-90',
        'opacity-100 scale-100',
        'ease-out', 'ease-in',
    ] }">
    <button @click="show = !show">Toggle</button>

    <!-- Kamu bisa membuat anonymous template di dalam x-data dan memanggilnya dengan ekspresi -->
    <div x-show="show" x-flux="template">Anonymous Template</div>

    <!-- (Masih Belum Di rilis ke npm! Jangan digunakan) Atau kamu juga bisa membuat anonymous template di dalam x-data dan memanggilnya dengan ekspresi dengan magic $template -->
    <div x-show="show" x-init="$flux(template)">Anonymous Template</div>
</section>

3. Membuat template di dalam konfigurasi

Panduan cara membuat template di dalam konfigurasi dan memanggilnya dengan directive x-flux, magic $flux dan magic dinamis $namaTemplate.

Magic dinamis ini terbuat secara otomatis saat kamu mendefinisikan sebuah template di dalam konfigurasi dengan aturan nama Kebab Case.

Perhatian: Cara ini tidak bisa digunakan apabila kamu menggunakan plugin ini dengan CDN.

import Alpine from 'alpinejs'
import Flux from 'alpinejs-flux'

Alpine.plugin(() => {
    Flux(Alpine, {
        // Kamu bisa menggunakan array untuk mendefinisikan template
        "translate-y-2": [
            "transition duration-300", // transition untuk enter dan leave
            "opacity-0 scale-90 translate-y-2", // enter-start | leave-end
            "opacity-100 scale-100 translate-y-0", // enter-end | leave-start
            "ease-out", "ease-in" // enter, leave
        ],
        // Atau kamu juga bisa menggunakan objek sama seperti milik AlpineJS untuk mendefinisikan template
        "rotate": {
            "enter": "transition-all ease-in-out transform duration-300",
            "enter-start": "opacity-0 scale-90",
            "enter-end": "opacity-100 scale-100 rotate-180",
            "leave": "transition-all ease-in-out transform duration-300",
            "leave-start": "opacity-100 scale-100",
            "leave-end": "opacity-0 scale-90"
        }
    });
});

Alpine.start()
<section x-data="{ show: false }">
    <button @click="show = !show">Toggle</button>

    <!-- Kamu bisa memanggil template yang sudah didefinisikan di konfigurasi -->
    <div x-show="show" x-flux="'translate-y-2'">Array dari Konfigurasi</div>
    <div x-show="show" x-flux="'rotate'">Objek dari Konfigurasi</div>

    <!-- Atau kamu bisa gunakan magic -->
    <div x-show="show" x-init="$flux('translate-y-2')">Array dari Konfigurasi</div>
    <div x-show="show" x-init="$flux('rotate')">Objek dari Konfigurasi</div>

    <!-- Atau kamu bisa gunakan magic dinamis -->
    <div x-show="show" x-init="$translateY2">Array dari Konfigurasi</div>
    <div x-show="show" x-init="$rotate">Objek dari Konfigurasi</div>
</section>

API Docs

Directive x-flux

Directive ini digunakan untuk membuat template secara inline, atau memanggil template yang sudah didefinisikan di konfigurasi. Inline dapat berupa array atau objek.

Parameter Tipe Deskripsi
inlineTemplateOrName (Array atau Object) atau String Template secara inline atau nama template yang sudah didefinisikan di konfigurasi
<div x-flux="[
    'transition duration-300',
    'opacity-0 scale-90',
    'opacity-100 scale-100',
    'ease-out', 'ease-in',
]">Ekspresi Array</div>

<div x-flux="{
    'enter': 'transition duration-300',
    'enter-start': 'opacity-0 scale-90',
    'enter-end': 'opacity-100 scale-100',
    'leave': 'transition duration-300',
    'leave-start': 'opacity-100 scale-100',
    'leave-end': 'opacity-0 scale-90',
}">Ekspresi Objek</div>

<div x-flux="'opacity-scale'">Panggil Template</div>

Magic $flux

$flux(templateName, newTemplate = null, applyToElement = true)

Digunakan untuk membuat template baru, atau memanggil template yang sudah didefinisikan di konfigurasi.

Parameter Tipe Deskripsi
templateName String Nama template, harus kebab-case
newTemplate Array atau Object Template baru yang akan dibuat
applyToElement Boolean Apakah template yang dibuat akan otomatis di terapkan pada elemen
<div x-init="$flux('opacity-scale', [
    'transition duration-300',
    'opacity-0 scale-90',
    'opacity-100 scale-100',
    'ease-out', 'ease-in',
])">Ekspresi Array</div>

<div x-init="$flux('opacity-scale', {
    'enter': 'transition duration-300',
    'enter-start': 'opacity-0 scale-90',
    'enter-end': 'opacity-100 scale-100',
    'leave': 'transition duration-300',
    'leave-start': 'opacity-100 scale-100',
    'leave-end': 'opacity-0 scale-90',
})">Ekspresi Objek</div>

<div x-init="$flux('opacity-scale')">Panggil Template</div>

Magic dinamis

Magic yang dibuat secara otomatis berdasarkan nama template yang sudah didefinisikan di konfigurasi. Digunakan untuk memanggil template yang sudah didefinisikan di konfigurasi.

Tidak ada parameter yang harus diberikan.

<div x-init="$opacityScale">Panggil Template</div>
Alpine.data('flux-demo', () => ({
    init() {
        this.$opacityScale();
    }
}));

Stats