logo image
  • Overview

    • View all components
    • Install required things
  • Common UI

    • App Logo
    • Avatar
    • Button
    • Badge
    • Typography

    • Forms

    • Notification
    • Modal
    • Card
    • Breadcrumb
    • Pagination
    • Top Progress Bar
    • Table
    • Item Grid
    • Youtube Video
  • Features UI

    • Live chat button
  • Sections

    • Hero Banner
    • FAQs
  • Layouts

    • common

    • TopBar Layout
    • SideBar Layout
  1. Home
  2. Components
  3. Common Ui
  4. Modal

Modal

Modals are essential UI elements for displaying messages, forms, or confirmations without navigating away from the current page. In this guide, you'll learn how to build a clean, responsive, and reusable modal component using Tailwind CSS in a Next.js (or React.js) application. Whether you're creating a login popup or a custom alert, this tutorial will help you do it efficiently.


Modal preview

Please install everything that's required

Before setup and using this component, please install all the required dependencies from this link (if you have never installed).

1. Setup codes

1.1. Setup Button components

First you need setup Button components in my docs.

1.2. Setup Modal components

Create a new component components/ui/Modal.tsx

jsx
"use client"; import { Dialog, DialogBackdrop, DialogPanel, DialogTitle } from "@headlessui/react"; import { ExclamationTriangleIcon } from "@heroicons/react/24/outline"; import Button from "./Button"; const Modal = ({ open, setOpen }) => { return ( <Dialog open={open} onClose={setOpen} className="relative z-10"> <DialogBackdrop transition className="data-closed:opacity-0 data-enter:duration-300 data-enter:ease-out data-leave:duration-200 data-leave:ease-in fixed inset-0 bg-gray-500/75 transition-opacity" /> <div className="fixed inset-0 z-10 w-screen overflow-y-auto"> <div className="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0"> <DialogPanel transition className="data-closed:translate-y-4 data-closed:opacity-0 data-enter:duration-300 data-enter:ease-out data-leave:duration-200 data-leave:ease-in data-closed:sm:translate-y-0 data-closed:sm:scale-95 relative transform overflow-hidden rounded-lg bg-white px-4 pb-4 pt-5 text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-lg sm:p-6" > <div className="sm:flex sm:items-start"> <div className="mx-auto flex size-12 shrink-0 items-center justify-center rounded-full bg-red-100 sm:mx-0 sm:size-10"> <ExclamationTriangleIcon aria-hidden="true" className="size-6 text-red-600" /> </div> <div className="mt-3 text-center sm:ml-4 sm:mt-0 sm:text-left"> <DialogTitle as="h3" className="text-base font-semibold text-gray-900"> Are you sure you want to delete this project? </DialogTitle> <div className="mt-2"> <p className="text-sm text-gray-500"> This action cannot be undone. Deleting this project will permanently remove all of its data. Please confirm if you wish to proceed. </p> </div> </div> </div> <div className="mt-5 sm:mt-4 sm:flex sm:justify-end sm:gap-2"> <Button variant="secondary" onClick={() => setOpen(false)}> Cancel </Button> <Button onClick={() => setOpen(false)} className="bg-system-error"> Delete </Button> </div> </DialogPanel> </div> </div> </Dialog> ); }; export default Modal;

2. Usages

You can create a state and pass into the Modal component.

jsx
"use client"; import React, { useState } from "react"; import Button from "@/components/Button"; import Modal from "@/components/Modal"; const PreviewModal = () => { const [open, setOpen] = useState(false); return ( <div className="flex justify-center rounded-lg border border-gray-300 py-14"> <Button onClick={() => setOpen(true)}>Open modal</Button> <Modal open={open} setOpen={setOpen} /> </div> ); }; export default PreviewModal;
Previous
Notification
Next
Card

On this page

  1. 1. Setup codes

    1. 1.1. Setup Button components
    2. 1.2. Setup Modal components
  2. 2. Usages