



'use client';
import {motion} from 'framer-motion';
import Image from 'next/image';
export function FolderTab({
files = ['/images/1.jpg', '/images/2.jpg', '/images/3.jpg', '/images/4.jpg', '/images/5.jpg'],
}: {
files: string[];
}) {
return (
<motion.div
initial="rest"
whileHover="hover"
animate="rest"
className="relative w-16 h-12 cursor-pointer"
style={{perspective: 800}}
>
<span
className="absolute inset-0 -translate-y-1 bg-orange-600/70 z-0"
style={{
clipPath: 'polygon(0% 25%, 20% 25%, 28% 0%, 60% 0%, 100% 0%, 100% 100%, 0% 100%)',
}}
/>
<div className="absolute inset-0 z-10">
{files.slice(0, 5).map((file, i) => (
<motion.div
key={i}
className="absolute bottom-[0.6px] -left-[0.5px] object-cover rounded-[2px]
shadow-sm border border-black/10 origin-bottom bg-accent aspect-square size-full"
variants={{
rest: {
x: i * 2,
y: -i * 2,
scale: 0.9,
},
hover: {
x: i * 10 - 12,
y: -i * 8 - 28,
rotate: i % 2 === 0 ? -6 : 6,
scale: 1,
},
}}
transition={{
type: 'spring',
stiffness: 260,
damping: 20,
}}
style={{zIndex: i}}
>
<Image
src={file}
priority={i === 0}
quality={60}
alt=""
fill
sizes="(max-width: 640px) 40px, 60px (max-width: 768px) 50px, 60px"
className="object-cover"
/>
</motion.div>
))}
</div>
<motion.div
className="absolute inset-0 z-20 bg-orange-500 border border-black/10 bg-linear-to-b from-black/10 to-transparent"
style={{
transformOrigin: 'bottom',
transformStyle: 'preserve-3d',
clipPath: 'polygon(0% 25%, 20% 25%, 28% 0%, 60% 0%, 100% 0%, 100% 100%, 0% 100%)',
}}
variants={{
rest: {rotateX: 0},
hover: {rotateX: -18},
}}
transition={{type: 'spring', stiffness: 320, damping: 20}}
>
<div className="absolute top-0 left-0 right-0 h-0.5 bg-white/30" />
<div className="absolute top-0 left-[18%] w-[30%] h-[25%] bg-white/10 rounded-sm" />
</motion.div>
</motion.div>
);
}
Folder Tab
A playful folder interaction with layered depth, hover expansion, and 3D lid animation using Framer Motion.
Framer MotionUI InteractionExperimental