Folder Peek
A 3D folder that swings open and fans its files out — in Classic, Neon and Da Vinci editions.
- Zero dependencies
- React + Tailwind
- Accessible
- Reduced-motion aware
Preview
Classic · Glossy desktop folder in your brand color. variant="classic"
On hover, tap or keyboard focus, the front flap rotates toward you in perspective, a warm light spills out of the folder, and the papers rise and fan with a staggered overshoot.
Installation
$ npx shadcn@latest add https://guetix.com/r/folder-peek.json
Uses the shadcn CLI. It creates components/guetix/folder-peek.tsx and installs nothing else.
Usage
example.tsx
"use client";
import FolderPeek, { type FolderVariant } from "@/components/guetix/folder-peek";
export default function FolderPeekDemo({ variant = "classic" }: { variant?: string }) {
return (
<FolderPeek
label={variant === "davinci" ? "Codice Atlantico" : "Case studies"}
variant={variant as FolderVariant}
files={[
{ name: "Brand-refresh.pdf", meta: "PDF · 2.4 MB", color: "#ef4444" },
{ name: "Dashboard.fig", meta: "Figma · 18 frames", color: "#a855f7" },
{ name: "Launch-notes.md", meta: "Markdown · 4 KB", color: "#22c55e" },
]}
/>
);
}
Project / case-study cardsDownloads sectionDocs categoriesEmpty states
Under the hood
The details that make it feel right, and that a one-line prompt usually misses:
- 01A single `--o` (0 → 1) custom property drives every transform with `calc()`, so one state flip animates all of the layers.
- 02Hover, `data-open` and `:has(:focus-visible)` all set `--o`, so mouse, touch and keyboard share the same motion.
- 03The papers' stagger uses `transition-delay: calc(var(--i) * 45ms)`, with no JavaScript timers.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | — | Folder title on the flap. |
| files | { name: string; meta?: string; color?: string }[] | — | Up to 4 are fanned out. |
| variant | "classic" | "neon" | "davinci" | "classic" | Art direction. |
| color | string | "#f59e0b" / "#4ade80" | Folder color (classic) or glow (neon). |
| open | boolean | — | Controlled open state. |
| onOpenChange | (open: boolean) => void | — | Called when toggled. |
| animated | boolean | true | false = the calm “Regular” version (no idle or ambient motion). |
Accessibility
- Toggle button with `aria-expanded` + `aria-controls`.
- File list available to screen readers.
- Reduced motion: no transitions.