Getting Started
Accordion
NewBarricade Tape
NewButtons
NewContact Section
NewFile Stack
NewGooey Words
NewGlowing Dots Background
NewImage Pile
NewJelly Loader
NewMask Cursor Effect
NewMagnet Tabs
NewMasonry Grid
NewPrismatic Haze Background
NewProjects Section
NewProximity Background
NewProximity Lift Grid
NewSkeumorphic Music Card
NewSpotlight Grid
NewTexts
NewTrading Card
NewContact 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
npm i framer-motion
Component
Create a file contact-section.tsx in your components folder and paste this code
'use client';
import { ReactNode, useState } from 'react';
import { AnimatePresence, motion } from 'framer-motion';
import Link from 'next/link';
type ContactType = {
name: string;
id: string;
logo: ReactNode;
message: string;
link: string;
};
const ContactSection = ({ contacts }: { contacts: ContactType[] }) => {
const [hovered, setHovered] = useState<string | null>(null);
return (
<div className="max-w-[600px] flex flex-col gap-4 w-full items-start justify-start">
<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">
<div
style={{
perspective: '1000px',
transform: 'rotateZ(-10deg) rotateY(25deg) rotateX(30deg)'
}}
className="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"
>
<AnimatePresence mode="popLayout">
{contacts.map((contact) => {
return (
contact.name === hovered && (
<motion.div
key={contact.name + contact.id}
initial={{
opacity: 0,
y: 100
}}
animate={{
opacity: 1,
y: 0
}}
exit={{
opacity: 0,
y: -100
}}
className="absolute inset-0 w-full h-full flex items-center justify-start whitespace-nowrap p-5 text-white"
>
<p className="text-xl sm:text-2xl">{contact.id}</p>
</motion.div>
)
);
})}
</AnimatePresence>
</div>
<AnimatePresence mode="popLayout">
{contacts.map((contact) => {
return (
contact.name === hovered && (
<motion.div
key={contact.name + contact.id + contact.logo + contact.message}
initial={{
opacity: 0
}}
animate={{
opacity: 1
}}
exit={{
opacity: 0
}}
className="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"
>
<p>{contact.message}</p>
</motion.div>
)
);
})}
</AnimatePresence>
</div>
<div className="flex items-center justify-start w-full">
{contacts.map((contact) => {
return (
<Link key={contact.id + contact.link} href={contact.link} target="_blank">
<motion.div
initial={{
y: 0,
scale: 1
}}
whileHover={{
y: -10,
scale: 1.1
}}
className="cursor-pointer p-3 shrink-0"
onTouchStart={() => setHovered(contact.name)}
onTouchEnd={() => setHovered(null)}
onMouseEnter={() => setHovered(contact.name)}
onMouseLeave={() => setHovered(null)}
>
{contact.logo}
</motion.div>
</Link>
);
})}
</div>
</div>
);
};
export default ContactSection;
Usage
<ContactSection
contacts={[
{
name: 'Gmail',
id: 'samitkapoor77@gmail.com',
link: 'mailto:samitkapoor77@gmail.com',
logo: <Mail />,
message: '100% chance I respond.'
},
{
name: 'X',
id: 'samitkapoorr',
link: 'https://x.com/samitkapoorr',
logo: <Twitter />,
message: '100% chance I respond.'
},
{
name: 'Linkedin',
id: 'Samit Kapoor',
link: 'https://linkedin.com/in/samit-kapoor',
logo: <Linkedin />,
message: "Can't promise a timely reply."
},
{
name: 'Instagram',
id: 'im_samit',
link: 'https://instagram.com/im_samit',
logo: <Instagram />,
message: "If I see it, I'll respond."
},
{
name: 'Github',
id: 'samitkapoor',
link: 'https://github.com/samitkapoor',
logo: <Github />,
message: "You can't text me here, but maybe follow?"
}
]}
/>