Contact Section
The Contact Section is a dynamic and interactive component designed to enhance user engagement by providing direct links to various social media platforms and contact methods. It features smooth animations and responsive design, ensuring a seamless experience across devices.
Follow below steps 👇🏻
Install dependencies
1npm i framer-motion
Component
Create a file contact-section.tsx in your components folder and paste this code
1'use client';23import { ReactNode, useState } from 'react';4import { AnimatePresence, motion } from 'framer-motion';5import Link from 'next/link';67type ContactType = {8name: string;9id: string;10logo: ReactNode;11message: string;12link: string;13};1415const ContactSection = ({ contacts }: { contacts: ContactType[] }) => {16const [hovered, setHovered] = useState<string | null>(null);1718return (19<div className="max-w-[600px] flex flex-col gap-4 w-full items-start justify-start">20<div className="flex sm:p-10 font-bold text-4xl w-full h-[300px] sm:h-[400px] rounded-3xl border-white/20 relative border-[1px] items-center justify-center">21<div22style={{23perspective: '1000px',24transform: 'rotateZ(-10deg) rotateY(25deg) rotateX(30deg)'25}}26className="h-[100px] sm:h-[150px] w-[95%] sm:w-[90%] bg-white/10 border-2 border-white/10 shadow-inner shadow-black/40 rounded-3xl flex items-center justify-center overflow-hidden"27>28<AnimatePresence mode="popLayout">29{contacts.map((contact) => {30return (31contact.name === hovered && (32<motion.div33key={contact.name + contact.id}34initial={{35opacity: 0,36y: 10037}}38animate={{39opacity: 1,40y: 041}}42exit={{43opacity: 0,44y: -10045}}46className="absolute inset-0 w-full h-full flex items-center justify-start whitespace-nowrap p-5 text-white"47>48<p className="text-xl sm:text-2xl">{contact.id}</p>49</motion.div>50)51);52})}53</AnimatePresence>54</div>55<AnimatePresence mode="popLayout">56{contacts.map((contact) => {57return (58contact.name === hovered && (59<motion.div60key={contact.name + contact.id + contact.logo + contact.message}61initial={{62opacity: 063}}64animate={{65opacity: 166}}67exit={{68opacity: 069}}70className="absolute bottom-0 w-full flex items-center justify-start whitespace-nowrap p-5 text-sm md:text-base max-w-[1000px] text-white/85"71>72<p>{contact.message}</p>73</motion.div>74)75);76})}77</AnimatePresence>78</div>7980<div className="flex items-center justify-start w-full">81{contacts.map((contact) => {82return (83<Link key={contact.id + contact.link} href={contact.link} target="_blank">84<motion.div85initial={{86y: 0,87scale: 188}}89whileHover={{90y: -10,91scale: 1.192}}93className="cursor-pointer p-3 shrink-0"94onTouchStart={() => setHovered(contact.name)}95onTouchEnd={() => setHovered(null)}96onMouseEnter={() => setHovered(contact.name)}97onMouseLeave={() => setHovered(null)}98>99{contact.logo}100</motion.div>101</Link>102);103})}104</div>105</div>106);107};108109export default ContactSection;
Usage
1<ContactSection2contacts={[3{4name: 'Gmail',567logo: <Mail />,8message: '100% chance I respond.'9},10{11name: 'X',12id: 'samitkapoorr',13link: 'https://x.com/samitkapoorr',14logo: <Twitter />,15message: '100% chance I respond.'16},17{18name: 'Linkedin',19id: 'Samit Kapoor',20link: 'https://linkedin.com/in/samit-kapoor',21logo: <Linkedin />,22message: "Can't promise a timely reply."23},24{25name: 'Instagram',26id: 'im_samit',27link: 'https://instagram.com/im_samit',28logo: <Instagram />,29message: "If I see it, I'll respond."30},31{32name: 'Github',33id: 'samitkapoor',34link: 'https://github.com/samitkapoor',35logo: <Github />,36message: "You can't text me here, but maybe follow?"37}38]}39/>
⭐️ Got a question or feedback?
Feel free to reach out!