"use client"
import React from "react";
import { motion, AnimatePresence } from "framer-motion";
import { X } from "lucide-react";
import { useState } from "react";
type cardProps = {
outerTitle?: string;
outerPara?: string;
innerTitle?: string;
desc?: string;
};
// ModalComponent
const ModalComponent = ({
outerTitle,
outerPara,
innerTitle,
desc,
}: cardProps) => {
const [isModalOpen, setIsModalOpen] = useState(false);
return (
<div className="p-8 bg-gray-100 h-full w-full">
<h1 className="text-2xl font-bold mb-4">
{outerTitle || "Expandable Code Modal Demo"}
</h1>
<p className="mb-4 text-gray-600">
{outerPara ||
"Click the button below to open a modal with expandable code blocks. Large code blocks will have an 'Expand' button in the top-right corner."}
</p>
<button
onClick={() => setIsModalOpen(true)}
className="px-6 py-3 bg-amber-400 text-white rounded-lg hover:bg-amber-700 transition-colors font-medium cursor-pointer"
>
Open
</button>
<Modal
isOpen={isModalOpen}
onClose={() => setIsModalOpen(false)}
title={innerTitle || "Code Documentation"}
description={desc || "hey there...."}
/>
</div>
);
};
export default ModalComponent;
interface ModalProps {
isOpen: boolean;
onClose: () => void;
title?: string;
description?: string;
}
const backdropVariants = {
visible: { opacity: 1 },
hidden: { opacity: 0 },
};
const modalVariants = {
hidden: { opacity: 0, scale: 0.95, y: -20 },
visible: { opacity: 1, scale: 1, y: 0 },
};
export const Modal: React.FC<ModalProps> = ({
isOpen,
onClose,
title,
description,
}) => {
return (
<AnimatePresence>
{isOpen && (
<>
{/* Overlay */}
<motion.div
className="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
variants={backdropVariants}
initial="hidden"
animate="visible"
exit="hidden"
onClick={onClose}
/>
{/* Modal content */}
<motion.div
className="fixed inset-0 z-100 flex items-center justify-center p-4 mt-5"
initial="hidden"
animate="visible"
exit="hidden"
>
<motion.div
className="thin-scrollbar w-full max-w-md overflow-auto md:max-w-2xl max-h-[80vh] p-2 md:p-6 bg-white dark:bg-zinc-900 shadow-xl border border-neutral-200 dark:border-white/10"
variants={modalVariants}
initial="hidden"
animate="visible"
exit="hidden"
role="dialog"
aria-modal="true"
tabIndex={-1}
onClick={(e) => e.stopPropagation()}
>
{/* Header */}
<div className="flex justify-between items-start mb-4">
{title && (
<h2 className="text-xl font-semibold text-gray-800 dark:text-white">
{title}
</h2>
)}
<button
onClick={onClose}
className="text-gray-400 hover:text-gray-900 dark:hover:text-gray-600 transition cursor-pointer"
aria-label="Close"
>
<X />
</button>
</div>
{/* Body */}
<div
className="text-sm text-gray-600 dark:text-gray-300 tiptap-content"
dangerouslySetInnerHTML={{ __html: description || "" }}
></div>
</motion.div>
</motion.div>
</>
)}
</AnimatePresence>
);
};