Membuat Modal Dengan Alpine JS

Pada artikel ini, kita akan melakukan latihan studi kasus membuat modal menggunakan Alpine JS. Jika kamu baru menemui artikel ini, saya rekomendasikan untuk membaca artikel sebelumnya yaitu Berkenalan Dengan Alpine JS. So Let’s start code!

Persiapan

Design modal yang akan kita gunakan pada artikel kali ini bisa kamu lihat disini. Kemudian silahkan kamu buat file HTML dengan nama index.html, kemudian masukkan kode berikut untuk inisialisasi pertama kali.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>⛰ Membuat Modal Dengan Alpine JS</title>

    <!-- Import Alpine JS -->
    <script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"></script>

    <!-- Fonts Google -->
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet" />
    <link href="https://fonts.googleapis.com/css2?family=Inter&display=swap" rel="stylesheet" />

    <!-- Tailwind -->
    <script src="https://cdn.tailwindcss.com"></script>

    <!-- Font Awesome -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"
        integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA=="
        crossorigin="anonymous" referrerpolicy="no-referrer" />

    <style>
        html {
            scroll-behavior: smooth;
        }

        body {
            font-family: "Poppins", sans-serif;
        }
    </style>
</head>

<body>

    <h1 class="font-bold text-center my-5">Membuat Modal Dengan Alpine JS 🎉</h1>

</body>

</html>

Maka apabila kita buka file HTML tersebut, didapatkan hasil:

Langkah selanjutnya mari kita lakukan proses slicing design modal tersebut menjadi code🔥

Slicing Design Modal

Untuk membuat button, kita akan menggunakan Tailwind CSS sebagai proses main styling utama. Maka akan didapatkan kode sebagai berikut:

<div class="flex flex-col justify-center items-center my-5">
  <!-- Button Open Modal -->
  <button
    class="py-2 px-4 rounded-md border text-gray-600 border-gray-600 mb-3 shadow-sm"
  >
    Open Modal
  </button>
</div>

Kemudian kita akan melakukan proses slicing dari modal berdasarkan design yang sudah dipersiapkan di awal:

<div class="flex flex-col justify-center items-center my-5">
  <!-- Button Open Modal -->
  <button
    class="py-2 px-4 rounded-md border text-gray-600 border-gray-600 mb-3 shadow-sm"
  >
    Open Modal
  </button>

  <!-- Modal -->
  <div class="py-2 p-1 rounded-md border border-gray-600 w-96 shadow-md">
    <div class="flex justify-end px-3">
      <button>
        <i class="fa-solid fa-x hover:pointer"></i>
      </button>
    </div>

    <!-- Modal Content -->
    <div class="p-3">
      <div class="flex items-center gap-x-3 text-gray-600 mb-5">
        <div
          class="bg-gray-200 p-2 rounded-md w-10 h-10 flex items-center justify-center"
        >
          <i class="fa-regular fa-circle-check"></i>
        </div>
        <div>
          <p class="font-bold">Sure you want to accept?</p>
          <p class="text-gray-500">Are you sure want to accept this></p>
        </div>
      </div>

      <div class="flex items-center gap-2">
        <button
          class="py-2 px-5 rounded-md border border-gray-600 text-gray-600 w-1/2"
        >
          No, cancel
        </button>
        <button class="py-2 px-5 rounded-md w-1/2 bg-gray-600 text-gray-100">
          Yes, confirm
        </button>
      </div>
    </div>
  </div>
</div>

Didapatkan hasil:

Implementasikan Alpine JS

Setelah kita berhasil membuat kode dari hasil design figma yang sudah kita siapkan, maka pada langkah ini kita akan buat agar komponen tersebut memiliki fungsionalitas layaknya komponen modal pada umumnya. Silahkan kamu perhatikan tag div yang membungkus antara button dan komponen modal sebelumnya:

<div
  class="flex flex-col justify-center items-center my-5"
  x-data="{openModal:false}"
>
  <!-- Button -->

  <!-- Modal -->
</div>

Pada kode tersebut kita menambahkan inisialisasi data dengan menggunakan directive dari Alpine JS yaitu x-data untuk menampung sebuah variabel dengan nama openModal yang berisikan nilai awal berupa tipe data boolean.

Kemudian kita akan menambahkan event ketika button tersebut di-klik maka akan mengubah isi nilai dari variabel openModal tersebut menjadi kebalikan dari nilai saat ini dengan menggunakan directive x-on:click, berikut implementasinya:

<div
  class="flex flex-col justify-center items-center my-5"
  x-data="{openModal:false}"
>
  <!-- Button -->
  <button
    class="py-2 px-4 rounded-md border text-gray-600 border-gray-600 mb-3 shadow-sm"
    x-on:click="openModal = !openModal"
  >
    Open Modal
  </button>

  <!-- Modal -->
</div>

Langkah selanjutnya kita akan menerapkan nilai dari variabel openModal tersebut terhadap modal yang sudah kita buat sebelumnya dengan menggunakan directive x-show:

<div
  class="flex flex-col justify-center items-center my-5"
  x-data="{openModal:false}"
>
  <!-- Button Open Modal -->
  <button
    class="py-2 px-4 rounded-md border text-gray-600 border-gray-600 mb-3 shadow-sm"
    x-on:click="openModal = !openModal"
  >
    Open Modal
  </button>

  <!-- Modal -->
  <div
    class="py-2 p-1 rounded-md border border-gray-600 w-96 shadow-md"
    x-show="openModal"
  >
    <!-- Modal Content -->
  </div>
</div>

Maka ketika button tersebut di-klik, akan didapatkan hasil seperti ini:

Sampai sini kamu sudah berhasil membuat komponen modal menggunakan Alpine JS. Langkah selanjutnya merupakan opsional, jadi kita akan menambahkan transisi sederhana ketika modal tersebut muncul kepada pengguna.

Tambahkan Transisi

Perhatikan tag div yang membungkus modal tersebut, lalu tambahkan baris kode berikut:

<!-- Modal -->
<div
  class="py-2 p-1 rounded-md border border-gray-600 w-96 shadow-md"
  x-show="openModal"
  x-on:click.away="openModal=false"

  x-transition:enter="transition transform ease-out duration-300"
  x-transition:enter-start="opacity-0 translate-y-[-20%] scale-90"
  x-transition:enter-end="opacity-100 translate-y-0 scale-100"
  x-transition:leave="transition transform ease-in duration-300"
  x-transition:leave-start="opacity-100 translate-y-0 scale-100"
  x-transition:leave-end="opacity-0 translate-y-[-20%] scale-90"
>
  <!-- Modal Content -->
</div>

Pada kode di atas kita memanfaatkan directive yang disediakan oleh Alpine JS yaitu x-transition yang bertujuan untuk membuat transisi ketika modal tersebut muncul maka akan secara halus dan tidak kaku.

Berikut adalah full source code yang sudah kita buat dalam artikel kali ini:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>⛰ Membuat Modal Dengan Alpine JS</title>

    <!-- Import Alpine JS -->
    <script
      defer
      src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"
    ></script>

    <!-- Fonts Google -->
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap"
      rel="stylesheet"
    />
    <link
      href="https://fonts.googleapis.com/css2?family=Inter&display=swap"
      rel="stylesheet"
    />

    <!-- Tailwind -->
    <script src="https://cdn.tailwindcss.com"></script>

    <!-- Font Awesome -->
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"
      integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA=="
      crossorigin="anonymous"
      referrerpolicy="no-referrer"
    />

    <style>
      html {
        scroll-behavior: smooth;
      }

      body {
        font-family: "Poppins", sans-serif;
      }
    </style>
  </head>

  <body>
    <div
      class="flex flex-col justify-center items-center my-5"
      x-data="{openModal:false}"
    >
      <!-- Button -->
      <button
        class="py-2 px-4 rounded-md border text-gray-600 border-gray-600 mb-3 shadow-sm"
        x-on:click="openModal = !openModal"
      >
        Open Modal
      </button>

      <!-- Modal -->
      <div
        class="py-2 p-1 rounded-md border border-gray-600 w-96 shadow-md"
        x-show="openModal"
        x-on:click.away="openModal=false"
        x-transition:enter="transition transform ease-out duration-300"
        x-transition:enter-start="opacity-0 translate-y-[-20%] scale-90"
        x-transition:enter-end="opacity-100 translate-y-0 scale-100"
        x-transition:leave="transition transform ease-in duration-300"
        x-transition:leave-start="opacity-100 translate-y-0 scale-100"
        x-transition:leave-end="opacity-0 translate-y-[-20%] scale-90"
      >
        <div class="flex justify-end px-3">
          <button x-on:click="openModal = false">
            <i class="fa-solid fa-x hover:pointer"></i>
          </button>
        </div>

        <!-- Modal Content -->
        <div class="p-3">
          <div class="flex items-center gap-x-3 text-gray-600 mb-5">
            <div
              class="bg-gray-200 p-2 rounded-md w-10 h-10 flex items-center justify-center"
            >
              <i class="fa-regular fa-circle-check"></i>
            </div>
            <div>
              <p class="font-bold">Sure you want to accept?</p>
              <p class="text-gray-500">Are you sure want to accept this?</p>
            </div>
          </div>

          <div class="flex items-center gap-2">
            <button
              class="py-2 px-5 rounded-md border border-gray-600 text-gray-600 w-1/2"
              x-on:click="openModal = false"
            >
              No, cancel
            </button>
            <button
              class="py-2 px-5 rounded-md w-1/2 bg-gray-600 text-gray-100"
              x-on:click="alert('Confirmed🎉')"
            >
              Yes, confirm
            </button>
          </div>
        </div>
      </div>
    </div>
  </body>
</html>

Kesimpulan

Ok, cukup untuk sampai disini. Saya berharap kamu belajar banyak dari artikel ini, dan jangan lupa tetap untuk terus melakukan eksplorasi dengan latihan berbagai studi kasus agar kamu bisa menguasainya secara keseluruhan tanpa adanya kendala.

Dan bagi kamu yang ingin mendalami dunia web development lebih lanjut, bisa bergabung dalam kelas premium yang disediakan oleh BuildWithAngga. Tunggu apalagi? Mari bergabung dan sampai jumpa dikelas👋