Docs
Go back
Component by
OV
OblivionTaxes 2026
📑
Taxes 2026 DataConfidential documents stored securely in this manila folder representation.
Invoices
Receipts
Contracts
TSX
manila-folder-stack
"use client"
import React, { useState } from "react"
import { motion } from "framer-motion"
import { cn } from "@/lib/utils"
export const componentMeta = {
name: "Manila Folder Stack",
description: "A skeuomorphic, delightfully tactile stacked folder layout. Clicking a folder smoothly brings it to the front.",
props: {
className: { type: "string", description: "Additional CSS classes", default: '""' }
}
}
const FOLDERS = [
{ id: "taxes", title: "Taxes 2026", color: "bg-[#F4E6B4]", tabColor: "bg-[#E6D491]", text: "text-yellow-900" },
{ id: "invoices", title: "Invoices", color: "bg-[#E2F0CB]", tabColor: "bg-[#C4DC9C]", text: "text-green-900" },
{ id: "receipts", title: "Receipts", color: "bg-[#FFDAC1]", tabColor: "bg-[#E7B896]", text: "text-orange-900" },
{ id: "contracts", title: "Contracts", color: "bg-[#E0E0E0]", tabColor: "bg-[#C9C9C9]", text: "text-neutral-800" },
]
export default function ManilaFolderStack({ className }: { className?: string }) {
const [activeFolder, setActiveFolder] = useState<string>("taxes")
return (
<div className={cn("w-full max-w-lg h-[500px] flex items-center justify-center relative p-8", className)}>
{FOLDERS.map((folder, index) => {
const isActive = activeFolder === folder.id
// When pushed to the back, folders visually stack upwards.
const yOffset = isActive ? 0 : -30 * index
const scale = isActive ? 1 : 1 - (index * 0.05)
const zIndex = isActive ? 40 : FOLDERS.length - index
return (
<motion.div
key={folder.id}
layout
onClick={() => setActiveFolder(folder.id)}
initial={false}
animate={{
y: yOffset,
scale: scale,
zIndex: zIndex,
}}
transition={{ type: "spring", stiffness: 250, damping: 25 }}
className="absolute bottom-12 w-full max-w-sm h-[320px] flex flex-col cursor-pointer transition-shadow"
style={{ transformOrigin: "bottom center" }}
whileHover={!isActive ? { y: yOffset - 10 } : {}}
>
{/* The Tab */}
<div className="flex px-4" style={{ zIndex: 10 }}>
<div
className={cn(
"px-5 py-2.5 rounded-t-xl font-bold tracking-wide shadow-[-2px_0px_5px_rgba(0,0,0,0.05)]",
folder.tabColor, folder.text
)}
style={{ marginLeft: `${index * 15}%` }}
>
{folder.title}
</div>
</div>
{/* The Folder Body */}
<div
className={cn(
"flex-1 rounded-2xl rounded-tl-none p-6 shadow-[0_10px_30px_rgba(0,0,0,0.15),inset_0_2px_4px_rgba(255,255,255,0.8)] border-t border-white/40",
folder.color
)}
>
{isActive && (
<motion.div
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.15, duration: 0.3 }}
className="w-full h-full bg-white/40 backdrop-blur-sm border border-white/50 border-dashed rounded-xl flex flex-col items-center justify-center p-4 gap-3 shadow-inner text-center"
>
<div className="w-12 h-12 rounded-full bg-white/60 flex items-center justify-center shadow-sm">
<span className="text-xl font-bold opacity-60">📑</span>
</div>
<span className={cn("font-medium uppercase tracking-widest text-sm opacity-80", folder.text)}>
{folder.title} Data
</span>
<p className="text-xs opacity-60 font-medium px-4">
Confidential documents stored securely in this manila folder representation.
</p>
</motion.div>
)}
</div>
</motion.div>
)
})}
</div>
)
}"use client"
import React, { useState } from "react"
import { motion } from "framer-motion"
import { cn } from "@/lib/utils"
export const componentMeta = {
name: "Manila Folder Stack",
description: "A skeuomorphic, delightfully tactile stacked folder layout. Clicking a folder smoothly brings it to the front.",
props: {
className: { type: "string", description: "Additional CSS classes", default: '""' }
}
}
const FOLDERS = [
{ id: "taxes", title: "Taxes 2026", color: "bg-[#F4E6B4]", tabColor: "bg-[#E6D491]", text: "text-yellow-900" },
{ id: "invoices", title: "Invoices", color: "bg-[#E2F0CB]", tabColor: "bg-[#C4DC9C]", text: "text-green-900" },
{ id: "receipts", title: "Receipts", color: "bg-[#FFDAC1]", tabColor: "bg-[#E7B896]", text: "text-orange-900" },
{ id: "contracts", title: "Contracts", color: "bg-[#E0E0E0]", tabColor: "bg-[#C9C9C9]", text: "text-neutral-800" },
]
export default function ManilaFolderStack({ className }: { className?: string }) {
const [activeFolder, setActiveFolder] = useState<string>("taxes")
return (
<div className={cn("w-full max-w-lg h-[500px] flex items-center justify-center relative p-8", className)}>
{FOLDERS.map((folder, index) => {
const isActive = activeFolder === folder.id
// When pushed to the back, folders visually stack upwards.
const yOffset = isActive ? 0 : -30 * index
const scale = isActive ? 1 : 1 - (index * 0.05)
const zIndex = isActive ? 40 : FOLDERS.length - index
return (
<motion.div
key={folder.id}
layout
onClick={() => setActiveFolder(folder.id)}
initial={false}
animate={{
y: yOffset,
scale: scale,
zIndex: zIndex,
}}
transition={{ type: "spring", stiffness: 250, damping: 25 }}
className="absolute bottom-12 w-full max-w-sm h-[320px] flex flex-col cursor-pointer transition-shadow"
style={{ transformOrigin: "bottom center" }}
whileHover={!isActive ? { y: yOffset - 10 } : {}}
>
{/* The Tab */}
<div className="flex px-4" style={{ zIndex: 10 }}>
<div
className={cn(
"px-5 py-2.5 rounded-t-xl font-bold tracking-wide shadow-[-2px_0px_5px_rgba(0,0,0,0.05)]",
folder.tabColor, folder.text
)}
style={{ marginLeft: `${index * 15}%` }}
>
{folder.title}
</div>
</div>
{/* The Folder Body */}
<div
className={cn(
"flex-1 rounded-2xl rounded-tl-none p-6 shadow-[0_10px_30px_rgba(0,0,0,0.15),inset_0_2px_4px_rgba(255,255,255,0.8)] border-t border-white/40",
folder.color
)}
>
{isActive && (
<motion.div
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.15, duration: 0.3 }}
className="w-full h-full bg-white/40 backdrop-blur-sm border border-white/50 border-dashed rounded-xl flex flex-col items-center justify-center p-4 gap-3 shadow-inner text-center"
>
<div className="w-12 h-12 rounded-full bg-white/60 flex items-center justify-center shadow-sm">
<span className="text-xl font-bold opacity-60">📑</span>
</div>
<span className={cn("font-medium uppercase tracking-widest text-sm opacity-80", folder.text)}>
{folder.title} Data
</span>
<p className="text-xs opacity-60 font-medium px-4">
Confidential documents stored securely in this manila folder representation.
</p>
</motion.div>
)}
</div>
</motion.div>
)
})}
</div>
)
}Save to favoritesCopy to Figma
React
Manila Folder Stack
A skeuomorphic, delightfully tactile stacked folder layout. Clicking a folder smoothly brings it to the front.
Installation
$ npx @cosmoo/oblivion add manila-folder-stackDependencies
npm install framer-motionUsage Example
tsx
import ManilaFolderStack from "@/components/oblivion/manila-folder-stack"
export default function Demo() {
return (
<div className="p-10 flex justify-center">
<ManilaFolderStack />
</div>
)
}import ManilaFolderStack from "@/components/oblivion/manila-folder-stack"
export default function Demo() {
return (
<div className="p-10 flex justify-center">
<ManilaFolderStack />
</div>
)
}