Himesh Dua

Component Preview

'use client';
import {motion} from 'framer-motion';
import Image from 'next/image';

export function FolderTab({
  files = [
    '/images/craft/1.jpeg',
    '/images/craft/2.jpeg',
    '/images/craft/4.jpeg',
    '/images/craft/5.jpeg',
  ],
}: {
  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

3D folder interaction with animated lid, layered depth, and smooth motion using Framer Motion.

Framer MotionUI AnimationFolder