Please use Desktop to view and interact with components
Blocks600msspring
Contact Block
Contact form with animated contact info cards, working hours, and interactive icons
contactformemailphonelocationshadcn
Useto navigate between components
Preview
Get In Touch
Have a project in mind? Let's discuss how we can work together
Working Hours
Monday - Friday9:00 AM - 6:00 PM
Saturday10:00 AM - 4:00 PM
SundayClosed
This component requires shadcn/ui
This component uses shadcn/ui components. Make sure you have shadcn/ui set up in your project.
- Install shadcn/ui:
npx shadcn-ui@latest init - Install required components based on the imports in the code (e.g.,
npx shadcn-ui@latest add button) - Ensure your
tailwind.config.tsandglobals.cssare configured as per shadcn/ui documentation
Code
TypeScript + React
'use client'
import { motion } from 'framer-motion'
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Textarea } from '@/components/ui/textarea'
import { Label } from '@/components/ui/label'
import { Mail, MapPin, Phone, Send } from 'lucide-react'
const contactInfo = [
{
icon: Mail,
label: 'Email',
value: 'hello@example.com',
href: 'mailto:hello@example.com',
},
{
icon: Phone,
label: 'Phone',
value: '+1 (555) 123-4567',
href: 'tel:+15551234567',
},
{
icon: MapPin,
label: 'Location',
value: 'San Francisco, CA',
href: '#',
},
]
export function ContactBlock() {
return (
<section className="bg-secondary/30 px-4 py-24 sm:px-6 lg:px-8">
<div className="mx-auto max-w-7xl">
<motion.div
initial={{ opacity: 0, y: -20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.6 }}
className="mb-16 text-center"
>
<h2 className="mb-4 text-4xl font-bold text-foreground md:text-5xl">
Get In Touch
</h2>
<p className="mx-auto max-w-2xl text-lg text-muted-foreground">
Have a project in mind? Let's discuss how we can work together
</p>
</motion.div>
<div className="grid gap-8 lg:grid-cols-2">
{/* Contact Form */}
<motion.div
initial={{ opacity: 0, x: -30 }}
whileInView={{ opacity: 1, x: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.6 }}
>
<Card className="border-border bg-card p-6 md:p-8">
<form className="space-y-6">
<div className="space-y-2">
<Label htmlFor="name">Name</Label>
<Input id="name" placeholder="Your name" className="bg-background" />
</div>
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Input
id="email"
type="email"
placeholder="your.email@example.com"
className="bg-background"
/>
</div>
<div className="space-y-2">
<Label htmlFor="subject">Subject</Label>
<Input
id="subject"
placeholder="How can I help you?"
className="bg-background"
/>
</div>
<div className="space-y-2">
<Label htmlFor="message">Message</Label>
<Textarea
id="message"
placeholder="Tell me about your project..."
rows={5}
className="resize-none bg-background"
/>
</div>
<Button type="submit" className="w-full gap-2">
Send Message
<Send className="h-4 w-4" />
</Button>
</form>
</Card>
</motion.div>
{/* Contact Info */}
<motion.div
initial={{ opacity: 0, x: 30 }}
whileInView={{ opacity: 1, x: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.6 }}
className="space-y-6"
>
{contactInfo.map((info, index) => (
<motion.div
key={index}
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ delay: index * 0.1, duration: 0.5 }}
>
<Card className="group border-border bg-card p-6 transition-all duration-300 hover:border-primary/50">
<a href={info.href} className="flex items-start gap-4">
<motion.div
whileHover={{ scale: 1.1, rotate: 5 }}
transition={{ duration: 0.3 }}
className="flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-lg bg-primary text-primary-foreground"
>
<info.icon className="h-5 w-5" />
</motion.div>
<div>
<h3 className="mb-1 font-semibold text-foreground transition-colors group-hover:text-primary">
{info.label}
</h3>
<p className="text-muted-foreground">{info.value}</p>
</div>
</a>
</Card>
</motion.div>
))}
<Card className="border-border bg-card p-6 md:p-8">
<h3 className="mb-4 text-xl font-semibold text-foreground">Working Hours</h3>
<div className="space-y-3 text-muted-foreground">
<div className="flex justify-between">
<span>Monday - Friday</span>
<span className="font-medium">9:00 AM - 6:00 PM</span>
</div>
<div className="flex justify-between">
<span>Saturday</span>
<span className="font-medium">10:00 AM - 4:00 PM</span>
</div>
<div className="flex justify-between">
<span>Sunday</span>
<span className="font-medium">Closed</span>
</div>
</div>
</Card>
</motion.div>
</div>
</div>
</section>
)
}
How to Use
- 1Install Framer Motion:
npm install framer-motion - 2Set up shadcn/ui: Install shadcn/ui components used in this code. Check the imports in the code above and install the required components (e.g.,
npx shadcn-ui@latest add button card) - 3Copy the code from above
- 4Paste it into your project and customize as needed
- 5Colors are customizable via Tailwind CSS classes. The default theme uses dark mode colors defined in your globals.css file