Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
1import {
2 Dialog,
3 DialogPanel,
4 DialogTitle,
5 Transition,
6 TransitionChild
7} from "@headlessui/react";
8import { XMarkIcon } from "@heroicons/react/24/outline";
9import { cva, type VariantProps } from "class-variance-authority";
10import type { ReactNode, SyntheticEvent } from "react";
11import { Fragment, memo } from "react";
12
13const modalVariants = cva(
14 "inline-block w-full scale-100 rounded-xl bg-white text-left align-bottom shadow-xl transition-all sm:my-8 sm:align-middle dark:bg-gray-800",
15 {
16 defaultVariants: { size: "sm" },
17 variants: {
18 size: {
19 lg: "sm:max-w-5xl",
20 md: "sm:max-w-3xl",
21 sm: "sm:max-w-lg",
22 xs: "sm:max-w-sm"
23 }
24 }
25 }
26);
27
28interface ModalProps extends VariantProps<typeof modalVariants> {
29 children: ReactNode | ReactNode[];
30 onClose?: () => void;
31 show: boolean;
32 title?: ReactNode;
33}
34
35const Modal = ({ children, onClose, show, size = "sm", title }: ModalProps) => {
36 const handleClose = (event: SyntheticEvent) => {
37 event.stopPropagation(); // This stops the event from propagating further
38 onClose?.();
39 };
40
41 return (
42 <Transition as={Fragment} show={show}>
43 <Dialog
44 as="div"
45 className="fixed inset-0 z-10 flex min-h-screen items-center justify-center overflow-y-auto p-4 text-center sm:block sm:p-0"
46 onClose={() => onClose?.()}
47 >
48 <span className="hidden sm:inline-block sm:h-screen sm:align-middle" />
49 <div
50 aria-hidden="true"
51 className="fixed inset-0 bg-gray-500/75 dark:bg-gray-900/80"
52 onClick={handleClose}
53 />
54 <TransitionChild
55 as={Fragment}
56 enter="ease-out duration-100"
57 enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
58 enterTo="opacity-100 translate-y-0 sm:scale-100"
59 leave="ease-in duration-100"
60 leaveFrom="opacity-100 translate-y-0 sm:scale-100"
61 leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
62 >
63 <DialogPanel className={modalVariants({ size })}>
64 {title ? (
65 <DialogTitle className="divider flex items-center justify-between px-5 py-3.5">
66 <b>{title}</b>
67 {onClose ? (
68 <button
69 className="rounded-full p-1 text-gray-800 hover:bg-gray-200 dark:text-gray-100 dark:hover:bg-gray-700"
70 onClick={(e) => {
71 e.stopPropagation();
72 onClose();
73 }}
74 type="button"
75 >
76 <XMarkIcon className="size-5" />
77 </button>
78 ) : null}
79 </DialogTitle>
80 ) : null}
81 {children}
82 </DialogPanel>
83 </TransitionChild>
84 </Dialog>
85 </Transition>
86 );
87};
88
89export default memo(Modal);