Please use Desktop to view and interact with components
Page Transitions500msspring
Stats Section
Animated statistics section with cards and counters
statsnumbersmetricscardsshadcn
Useto navigate between components
Preview
Trusted by Thousands
Join millions of users who trust our platform
50,000+
Active Users
99.9%
Uptime
150+
Awards Won
1,000+
Features
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 { useRef } from 'react'
import { useInView } from 'framer-motion'
import { Users, TrendingUp, Award, Zap } from 'lucide-react'
import { Card, CardContent } from '@/components/ui/card'
const stats = [
{ icon: Users, value: 50000, label: 'Active Users', suffix: '+' },
{ icon: TrendingUp, value: 99.9, label: 'Uptime', suffix: '%' },
{ icon: Award, value: 150, label: 'Awards Won', suffix: '+' },
{ icon: Zap, value: 1000, label: 'Features', suffix: '+' },
]
export function StatsSection() {
const ref = useRef(null)
const isInView = useInView(ref, { once: true })
return (
<div ref={ref} className="w-full px-4 py-16">
<div className="mx-auto max-w-6xl">
<motion.div
initial={{ opacity: 0, y: 30 }}
animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 30 }}
transition={{ duration: 0.6 }}
className="mb-12 text-center"
>
<h2 className="mb-4 text-3xl font-bold sm:text-4xl md:text-5xl">Trusted by Thousands</h2>
<p className="text-sm text-[var(--foreground)]/70 sm:text-base md:text-lg">
Join millions of users who trust our platform
</p>
</motion.div>
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
{stats.map((stat, index) => {
const Icon = stat.icon
return (
<motion.div
key={stat.label}
initial={{ opacity: 0, y: 50, scale: 0.9 }}
animate={isInView ? { opacity: 1, y: 0, scale: 1 } : { opacity: 0, y: 50, scale: 0.9 }}
transition={{ duration: 0.5, delay: index * 0.1 }}
>
<Card className="relative overflow-hidden bg-[var(--card-bg)] transition-all hover:shadow-lg">
<CardContent className="p-6">
<motion.div
initial={{ scale: 0, rotate: -180 }}
animate={isInView ? { scale: 1, rotate: 0 } : { scale: 0, rotate: -180 }}
transition={{ delay: index * 0.1 + 0.2, type: 'spring', stiffness: 200 }}
className="mb-4 inline-flex rounded-lg bg-accent/10 p-3"
>
<Icon className="h-6 w-6 text-white" />
</motion.div>
<motion.h3
initial={{ opacity: 0 }}
animate={isInView ? { opacity: 1 } : { opacity: 0 }}
transition={{ delay: index * 0.1 + 0.3 }}
className="mb-2 text-3xl font-bold"
>
{stat.value.toLocaleString()}
{stat.suffix}
</motion.h3>
<motion.p
initial={{ opacity: 0 }}
animate={isInView ? { opacity: 1 } : { opacity: 0 }}
transition={{ delay: index * 0.1 + 0.4 }}
className="text-sm text-[var(--foreground)]/70"
>
{stat.label}
</motion.p>
</CardContent>
</Card>
</motion.div>
)
})}
</div>
</div>
</div>
)
}
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