English | Indonesia
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.
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,
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.
<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>
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()
Ada beberapa cara untuk menggunakan plugin ini.
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>
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>
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>
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>
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 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();
}
}));