Skip to content

Instantly share code, notes, and snippets.

@clqu
Created May 9, 2022 19:01
Show Gist options
  • Save clqu/32883b5bc2146bdc545a261b49c3c5eb to your computer and use it in GitHub Desktop.
Save clqu/32883b5bc2146bdc545a261b49c3c5eb to your computer and use it in GitHub Desktop.
This is a modal component made with TailwindCSS and Next.js.
import Modal from '../Modal'
export default function Home() {
return (
<>
<Modal
title={"Modal Title"}
content={"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."}
onConfirm={() => console.log('Button confirm')}
onDiscard={() => console.log('Button discard')}
buttons={[
{ role: "custom", onClick: () => console.log("custom test"), toClose: true, classes: "bg-zinc-500/20 px-4 py-2 rounded-lg hover:bg-zinc-500/30 transition-all duration-200", label: "Custom" },
{ role: "discard", toClose: true, classes: "bg-zinc-500/20 px-4 py-2 rounded-lg hover:bg-zinc-500/30 transition-all duration-200", label: "Discard" },
{ role: "confirm", toClose: false, classes: "bg-green-500 px-4 py-2 rounded-lg hover:bg-green-600 transition-all duration-200", label: "Confirm" }
]}
>
<div>açmak için tıkla</div>
</Modal>
</>
)
}
const { Fragment, useState, useEffect } = require("react");
const { Transition } = require("@headlessui/react");
module.exports = ({
title = "",
content = "",
buttons = [],
classes = "",
onDiscard = "",
onConfirm = "",
children
}) => {
let [ isOpen, setIsOpen ] = useState(false);
useEffect(() => {
setIsOpen(isOpen);
if(!isOpen) {
document.documentElement.style.overflow = "auto";
} else {
document.documentElement.style.overflow = "hidden";
}
}, [isOpen]);
const HandleChange = () => {
setIsOpen(!isOpen);
}
return <>
<div onClick={() => HandleChange()}>
{children}
</div>
<Transition show={isOpen}>
<Transition.Child
as={Fragment}
enter="transition-all duration-200"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition-all duration-200"
leaveTo="opacity-0"
leaveFrom="opacity-100"
>
<div style={{ zIndex: '1' }} onClick={() => HandleChange()} className="w-full h-full left-0 top-0 bg-black/50 fixed" />
</Transition.Child>
<Transition.Child
as={Fragment}
enter="transition-all duration-200"
enterFrom="opacity-0 scale-75"
enterTo="opacity-100 scale-100"
leave="transition-all duration-200"
leaveTo="opacity-0 scale-75"
leaveFrom="opacity-100 scale-100"
>
<div style={{ zIndex: '2' }} className="flex justify-center items-center h-full w-full fixed">
<div className={`max-w-[28rem] w-full ${classes ? classes : 'p-4 bg-white rounded-lg'}`}>
<div className="w-full flex justify-between items-center mb-6">
<p className="font-medium text-lg">{title}</p>
<div onClick={() => HandleChange()} className="w-8 h-8 flex justify-center items-center rounded-lg transition-all duration-200 cursor-pointer hover:bg-zinc-500/20">
<svg width="24px" height="24px" viewBox="0 0 36 36" version="1.1" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink">
<path className="clr-i-outline clr-i-outline-path-1" d="M19.41,18l8.29-8.29a1,1,0,0,0-1.41-1.41L18,16.59,9.71,8.29A1,1,0,0,0,8.29,9.71L16.59,18,8.29,26.29a1,1,0,1,0,1.41,1.41L18,19.41l8.29,8.29a1,1,0,0,0,1.41-1.41Z" />
<rect x={0} y={0} width={36} height={36} fillOpacity={0} />
</svg>
</div>
</div>
<p className="text-md">{content}</p>
<div className="mt-6 flex justify-end items-center gap-2">
{buttons.map((button, index) => (
<button
onClick={() => {
if(button.role === "discard") {
onDiscard();
}
if(button.role === "confirm") {
onConfirm();
}
if(button.role === "custom") {
button.onClick();
}
if(button.toClose) {
setIsOpen(false);
}
}}
key={index}
className={button.classes}
>
{button.label}
</button>
))}
</div>
</div>
</div>
</Transition.Child>
</Transition>
</>
}
@akawajid
Copy link

It's working fine though, but we could have a prop to change the open state dynamically.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment