Install component
"use client"; import React from "react"; import { Modal, ModalBody, ModalContent, ModalFooter, ModalTrigger, } from "@/components/ui/animated-modal"; import { Button } from "@/components/ui/button"; import Image from "next/image"; import { motion } from "framer-motion"; export function AnimatedModalDemo() { const images = [ "https://images.unsplash.com/photo-1517322048670-4fba75cbbb62?q=80&w=3000&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", "https://images.unsplash.com/photo-1573790387438-4da905039392?q=80&w=3425&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", "https://images.unsplash.com/photo-1555400038-63f5ba517a47?q=80&w=3540&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", "https://images.unsplash.com/photo-1554931670-4ebfabf6e7a9?q=80&w=3387&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", "https://images.unsplash.com/photo-1546484475-7f7bd55792da?q=80&w=2581&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", ]; return ( <div className="py-40 flex items-center justify-center"> <Modal> <ModalTrigger asChild> <Button variant="default" className="relative group/modal-btn bg-black dark:bg-white dark:text-black text-white hover:bg-black/90 dark:hover:bg-white/90" > <span className="group-hover/modal-btn:translate-x-40 text-center transition duration-500"> Book your flight </span> <div className="-translate-x-40 group-hover/modal-btn:translate-x-0 flex items-center justify-center absolute inset-0 transition duration-500 text-white dark:text-black z-20"> ✈️ </div> </Button> </ModalTrigger> <ModalBody> <ModalContent> <h4 className="text-lg md:text-2xl text-neutral-600 dark:text-neutral-100 font-bold text-center mb-8"> Book your trip to{" "} <span className="px-1 py-0.5 rounded-md bg-gray-100 dark:bg-neutral-800 dark:border-neutral-700 border border-gray-200"> Bali </span>{" "} now! ✈️ </h4> <div className="flex justify-center items-center"> {images.map((image, idx) => ( <motion.div key={"images" + idx} style={{ rotate: Math.random() * 20 - 10, }} whileHover={{ scale: 1.1, rotate: 0, zIndex: 100, }} whileTap={{ scale: 1.1, rotate: 0, zIndex: 100, }} className="rounded-xl -mr-4 mt-4 p-1 bg-white dark:bg-neutral-800 dark:border-neutral-700 border border-neutral-100 flex-shrink-0 overflow-hidden" > <Image src={image} alt="bali images" width="500" height="500" className="rounded-lg h-20 w-20 md:h-40 md:w-40 object-cover flex-shrink-0" /> </motion.div> ))} </div> <div className="py-10 flex flex-wrap gap-x-4 gap-y-6 items-start justify-start max-w-sm mx-auto"> <div className="flex items-center justify-center"> <PlaneIcon className="mr-1 text-neutral-700 dark:text-neutral-300 h-4 w-4" /> <span className="text-neutral-700 dark:text-neutral-300 text-sm"> 5 connecting flights </span> </div> <div className="flex items-center justify-center"> <ElevatorIcon className="mr-1 text-neutral-700 dark:text-neutral-300 h-4 w-4" /> <span className="text-neutral-700 dark:text-neutral-300 text-sm"> 12 hotels </span> </div> <div className="flex items-center justify-center"> <VacationIcon className="mr-1 text-neutral-700 dark:text-neutral-300 h-4 w-4" /> <span className="text-neutral-700 dark:text-neutral-300 text-sm"> 69 visiting spots </span> </div> <div className="flex items-center justify-center"> <FoodIcon className="mr-1 text-neutral-700 dark:text-neutral-300 h-4 w-4" /> <span className="text-neutral-700 dark:text-neutral-300 text-sm"> Good food everyday </span> </div> <div className="flex items-center justify-center"> <MicIcon className="mr-1 text-neutral-700 dark:text-neutral-300 h-4 w-4" /> <span className="text-neutral-700 dark:text-neutral-300 text-sm"> Open Mic </span> </div> <div className="flex items-center justify-center"> <ParachuteIcon className="mr-1 text-neutral-700 dark:text-neutral-300 h-4 w-4" /> <span className="text-neutral-700 dark:text-neutral-300 text-sm"> Paragliding </span> </div> </div> </ModalContent> <ModalFooter className="gap-4"> <Button variant="secondary" className="w-28 bg-gray-200 text-black dark:bg-black dark:border-black dark:text-white border border-gray-300" > Cancel </Button> <Button variant="default" className="w-28 bg-black text-white dark:bg-white dark:text-black border border-black" > Book Now </Button> </ModalFooter> </ModalBody> </Modal> </div> ); } const PlaneIcon = ({ className }: { className?: string }) => { return ( <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className} > <path stroke="none" d="M0 0h24v24H0z" fill="none" /> <path d="M16 10h4a2 2 0 0 1 0 4h-4l-4 7h-3l2 -7h-4l-2 2h-3l2 -4l-2 -4h3l2 2h4l-2 -7h3z" /> </svg> ); }; const VacationIcon = ({ className }: { className?: string }) => { return ( <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className} > <path stroke="none" d="M0 0h24v24H0z" fill="none" /> <path d="M17.553 16.75a7.5 7.5 0 0 0 -10.606 0" /> <path d="M18 3.804a6 6 0 0 0 -8.196 2.196l10.392 6a6 6 0 0 0 -2.196 -8.196z" /> <path d="M16.732 10c1.658 -2.87 2.225 -5.644 1.268 -6.196c-.957 -.552 -3.075 1.326 -4.732 4.196" /> <path d="M15 9l-3 5.196" /> <path d="M3 19.25a2.4 2.4 0 0 1 1 -.25a2.4 2.4 0 0 1 2 1a2.4 2.4 0 0 0 2 1a2.4 2.4 0 0 0 2 -1a2.4 2.4 0 0 1 2 -1a2.4 2.4 0 0 1 2 1a2.4 2.4 0 0 0 2 1a2.4 2.4 0 0 0 2 -1a2.4 2.4 0 0 1 2 -1a2.4 2.4 0 0 1 1 .25" /> </svg> ); }; const ElevatorIcon = ({ className }: { className?: string }) => { return ( <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className} > <path stroke="none" d="M0 0h24v24H0z" fill="none" /> <path d="M5 4m0 1a1 1 0 0 1 1 -1h12a1 1 0 0 1 1 1v14a1 1 0 0 1 -1 1h-12a1 1 0 0 1 -1 -1z" /> <path d="M10 10l2 -2l2 2" /> <path d="M10 14l2 2l2 -2" /> </svg> ); }; const FoodIcon = ({ className }: { className?: string }) => { return ( <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className} > <path stroke="none" d="M0 0h24v24H0z" fill="none" /> <path d="M20 20c0 -3.952 -.966 -16 -4.038 -16s-3.962 9.087 -3.962 14.756c0 -5.669 -.896 -14.756 -3.962 -14.756c-3.065 0 -4.038 12.048 -4.038 16" /> </svg> ); }; const MicIcon = ({ className }: { className?: string }) => { return ( <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className} > <path stroke="none" d="M0 0h24v24H0z" fill="none" /> <path d="M15 12.9a5 5 0 1 0 -3.902 -3.9" /> <path d="M15 12.9l-3.902 -3.899l-7.513 8.584a2 2 0 1 0 2.827 2.83l8.588 -7.515z" /> </svg> ); }; const ParachuteIcon = ({ className }: { className?: string }) => { return ( <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className} > <path stroke="none" d="M0 0h24v24H0z" fill="none" /> <path d="M22 12a10 10 0 1 0 -20 0" /> <path d="M22 12c0 -1.66 -1.46 -3 -3.25 -3c-1.8 0 -3.25 1.34 -3.25 3c0 -1.66 -1.57 -3 -3.5 -3s-3.5 1.34 -3.5 3c0 -1.66 -1.46 -3 -3.25 -3c-1.8 0 -3.25 1.34 -3.25 3" /> <path d="M2 12l10 10l-3.5 -10" /> <path d="M15.5 12l-3.5 10l10 -10" /> </svg> ); };