lightswind
Version:
A collection of beautifully crafted React Components, Blocks & Templates for Modern Developers. Create stunning web applications effortlessly by using our 160+ professional and animated react components.
61 lines (60 loc) • 3.64 kB
JavaScript
// @ts-nocheck
"use client";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useState } from "react";
import { AnimatePresence, motion } from "framer-motion";
import { VideoIcon, X } from "lucide-react";
import { cn } from "../../lib/utils";
const slideVariants = {
bottom: {
initial: { y: "100%", opacity: 0 },
animate: { y: 0, opacity: 1 },
exit: { y: "100%", opacity: 0 },
},
center: {
initial: { scale: 0.7, opacity: 0 },
animate: { scale: 1, opacity: 1 },
exit: { scale: 0.7, opacity: 0 },
},
top: {
initial: { y: "-100%", opacity: 0 },
animate: { y: 0, opacity: 1 },
exit: { y: "-100%", opacity: 0 },
},
left: {
initial: { x: "-100%", opacity: 0 },
animate: { x: 0, opacity: 1 },
exit: { x: "-100%", opacity: 0 },
},
right: {
initial: { x: "100%", opacity: 0 },
animate: { x: 0, opacity: 1 },
exit: { x: "100%", opacity: 0 },
},
fade: {
initial: { opacity: 0 },
animate: { opacity: 1 },
exit: { opacity: 0 },
},
"slide-up-fade-out": {
initial: { y: "100%", opacity: 0 },
animate: { y: 0, opacity: 1 },
exit: { y: "-100%", opacity: 0 },
},
"slide-left-fade-out": {
initial: { x: "-100%", opacity: 0 },
animate: { x: 0, opacity: 1 },
exit: { x: "100%", opacity: 0 },
},
};
export function VideoModal({ sourceUrl, previewImage, previewAlt = "Preview thumbnail", transition = "center", containerClass, }) {
const [open, setOpen] = useState(false);
const variant = slideVariants[transition];
return (_jsxs("div", { className: cn("relative", containerClass), children: [_jsxs("div", { role: "button", className: "group relative overflow-hidden rounded-xl border shadow-lg \r\n transition-all cursor-pointer h-64 object-cover bg-black/60 inset-0 ", onClick: () => setOpen(true), children: [_jsx("img", { src: previewImage, alt: previewAlt, className: "w-full object-cover transition duration-200 group-hover:brightness-75 \r\n " }), _jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: _jsx("div", { className: "flex size-24 items-center justify-center rounded-full bg-white/10 backdrop-blur-sm", children: _jsx(VideoIcon, { className: "text-white size-12 transition-transform group-hover:scale-110" }) }) })] }), _jsx(AnimatePresence, { children: open && (_jsx(motion.div, { className: "fixed inset-0 z-50 flex \r\n items-center justify-center \r\n bg-black/60 backdrop-blur-sm", onClick: () => setOpen(false), initial: "initial", animate: "animate", exit: "exit", variants: fadeOverlay, children: _jsxs(motion.div, { ...variant, transition: { type: "spring", damping: 25, stiffness: 300 }, onClick: (e) => e.stopPropagation(), className: "relative mx-4 w-full max-w-5xl h-[70vh]", children: [_jsx("button", { onClick: () => setOpen(false), className: "absolute -top-14 right-0 z-50 \r\n rounded-full bg-black/70 p-2 text-white hover:bg-black/90", children: _jsx(X, { className: "size-5" }) }), _jsx("div", { className: "w-full h-full overflow-hidden rounded-2xl border shadow-2xl", children: _jsx("iframe", { src: sourceUrl, allowFullScreen: true, className: "w-full h-full rounded-2xl", allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" }) })] }) })) })] }));
}
// Background fade animation for modal
const fadeOverlay = {
initial: { opacity: 0 },
animate: { opacity: 1 },
exit: { opacity: 0 },
};