{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "folder",
  "type": "registry:block",
  "title": "Folder",
  "description": "Folder",
  "files": [
    {
      "path": "components/usages/folderusage.tsx",
      "content": "\"use client\";\n\nimport React from \"react\";\n\nimport Folder from \"@/registry/open-source/folder\";\n\nexport default function Usage() {\n\treturn (\n\t\t<div className=\"h-screen w-full flex items-center justify-center relative overflow-hidden bg-background\">\n\t\t\t<div style={{ height: \"600px\", position: \"relative\" }}>\n\t\t\t\t<Folder size={2} color=\"#00d8ff\" className=\"custom-folder\" />\n\t\t\t</div>{\" \"}\n\t\t</div>\n\t);\n}\n",
      "type": "registry:block",
      "target": "~/example.tsx"
    },
    {
      "path": "components/usages/folderusage.tsx",
      "content": "\"use client\";\n\nimport React from \"react\";\n\nimport Folder from \"@/registry/open-source/folder\";\n\nexport default function Usage() {\n\treturn (\n\t\t<div className=\"h-screen w-full flex items-center justify-center relative overflow-hidden bg-background\">\n\t\t\t<div style={{ height: \"600px\", position: \"relative\" }}>\n\t\t\t\t<Folder size={2} color=\"#00d8ff\" className=\"custom-folder\" />\n\t\t\t</div>{\" \"}\n\t\t</div>\n\t);\n}\n",
      "type": "registry:ui"
    },
    {
      "path": "registry/open-source/folder.tsx",
      "content": "import React, { useState } from \"react\";\n\n// Credit:\n// https://www.reactbits.dev/components/folder\n\ninterface FolderProps {\n\tcolor?: string;\n\tsize?: number;\n\titems?: React.ReactNode[];\n\tclassName?: string;\n}\n\nconst darkenColor = (hex: string, percent: number): string => {\n\tlet color = hex.startsWith(\"#\") ? hex.slice(1) : hex;\n\tif (color.length === 3) {\n\t\tcolor = color\n\t\t\t.split(\"\")\n\t\t\t.map((c) => c + c)\n\t\t\t.join(\"\");\n\t}\n\tconst num = parseInt(color, 16);\n\tlet r = (num >> 16) & 0xff;\n\tlet g = (num >> 8) & 0xff;\n\tlet b = num & 0xff;\n\tr = Math.max(0, Math.min(255, Math.floor(r * (1 - percent))));\n\tg = Math.max(0, Math.min(255, Math.floor(g * (1 - percent))));\n\tb = Math.max(0, Math.min(255, Math.floor(b * (1 - percent))));\n\treturn (\n\t\t\"#\" +\n\t\t((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1).toUpperCase()\n\t);\n};\n\nconst Folder: React.FC<FolderProps> = ({\n\tcolor = \"#00d8ff\",\n\tsize = 1,\n\titems = [],\n\tclassName = \"\",\n}) => {\n\tconst maxItems = 3;\n\tconst papers = items.slice(0, maxItems);\n\twhile (papers.length < maxItems) {\n\t\tpapers.push(null);\n\t}\n\n\tconst [open, setOpen] = useState(false);\n\tconst [paperOffsets, setPaperOffsets] = useState<{ x: number; y: number }[]>(\n\t\tArray.from({ length: maxItems }, () => ({ x: 0, y: 0 }))\n\t);\n\n\tconst folderBackColor = darkenColor(color, 0.08);\n\tconst paper1 = darkenColor(\"#ffffff\", 0.1);\n\tconst paper2 = darkenColor(\"#ffffff\", 0.05);\n\tconst paper3 = \"#ffffff\";\n\n\tconst handleClick = () => {\n\t\tsetOpen((prev) => !prev);\n\t\tif (open) {\n\t\t\tsetPaperOffsets(\n\t\t\t\tArray.from({ length: maxItems }, () => ({ x: 0, y: 0 }))\n\t\t\t);\n\t\t}\n\t};\n\n\tconst handlePaperMouseMove = (\n\t\te: React.MouseEvent<HTMLDivElement, MouseEvent>,\n\t\tindex: number\n\t) => {\n\t\tif (!open) return;\n\t\tconst rect = e.currentTarget.getBoundingClientRect();\n\t\tconst centerX = rect.left + rect.width / 2;\n\t\tconst centerY = rect.top + rect.height / 2;\n\t\tconst offsetX = (e.clientX - centerX) * 0.15;\n\t\tconst offsetY = (e.clientY - centerY) * 0.15;\n\t\tsetPaperOffsets((prev) => {\n\t\t\tconst newOffsets = [...prev];\n\t\t\tnewOffsets[index] = { x: offsetX, y: offsetY };\n\t\t\treturn newOffsets;\n\t\t});\n\t};\n\n\tconst handlePaperMouseLeave = (\n\t\te: React.MouseEvent<HTMLDivElement, MouseEvent>,\n\t\tindex: number\n\t) => {\n\t\tsetPaperOffsets((prev) => {\n\t\t\tconst newOffsets = [...prev];\n\t\t\tnewOffsets[index] = { x: 0, y: 0 };\n\t\t\treturn newOffsets;\n\t\t});\n\t};\n\n\tconst folderStyle: React.CSSProperties = {\n\t\t\"--folder-color\": color,\n\t\t\"--folder-back-color\": folderBackColor,\n\t\t\"--paper-1\": paper1,\n\t\t\"--paper-2\": paper2,\n\t\t\"--paper-3\": paper3,\n\t} as React.CSSProperties;\n\n\t// Outer scale style\n\tconst scaleStyle = { transform: `scale(${size})` };\n\n\tconst getOpenTransform = (index: number) => {\n\t\tif (index === 0) return \"translate(-120%, -70%) rotate(-15deg)\";\n\t\tif (index === 1) return \"translate(10%, -70%) rotate(15deg)\";\n\t\tif (index === 2) return \"translate(-50%, -100%) rotate(5deg)\";\n\t\treturn \"\";\n\t};\n\n\treturn (\n\t\t<div style={scaleStyle} className={className}>\n\t\t\t<div\n\t\t\t\tclassName={`group relative transition-transform duration-200 ease-in cursor-pointer ${\n\t\t\t\t\t!open ? \"hover:-translate-y-2\" : \"\"\n\t\t\t\t}`}\n\t\t\t\tstyle={{\n\t\t\t\t\t...folderStyle,\n\t\t\t\t\ttransform: open ? \"translateY(-8px)\" : undefined,\n\t\t\t\t}}\n\t\t\t\tonClick={handleClick}\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName=\"relative w-[100px] h-[80px] rounded-tl-0 rounded-tr-[10px] rounded-br-[10px] rounded-bl-[10px] bg-background\"\n\t\t\t\t\tstyle={{ backgroundColor: folderBackColor }}\n\t\t\t\t>\n\t\t\t\t\t<span\n\t\t\t\t\t\tclassName=\"absolute z-0 bottom-[98%] left-0 w-[30px] h-[10px] rounded-tl-[5px] rounded-tr-[5px] rounded-bl-0 rounded-br-0 bg-background\"\n\t\t\t\t\t\tstyle={{ backgroundColor: folderBackColor }}\n\t\t\t\t\t></span>\n\t\t\t\t\t{/* Render papers */}\n\t\t\t\t\t{papers.map((item, i) => {\n\t\t\t\t\t\tlet sizeClasses = \"\";\n\t\t\t\t\t\tif (i === 0)\n\t\t\t\t\t\t\tsizeClasses = open ? \"w-[70%] h-[80%]\" : \"w-[70%] h-[80%]\";\n\t\t\t\t\t\tif (i === 1)\n\t\t\t\t\t\t\tsizeClasses = open ? \"w-[80%] h-[80%]\" : \"w-[80%] h-[70%]\";\n\t\t\t\t\t\tif (i === 2)\n\t\t\t\t\t\t\tsizeClasses = open ? \"w-[90%] h-[80%]\" : \"w-[90%] h-[60%]\";\n\n\t\t\t\t\t\tconst transformStyle = open\n\t\t\t\t\t\t\t? `${getOpenTransform(i)} translate(${\n\t\t\t\t\t\t\t\t\tpaperOffsets[i].x\n\t\t\t\t\t\t\t\t}px, ${paperOffsets[i].y}px)`\n\t\t\t\t\t\t\t: undefined;\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tkey={i + \"folder\"}\n\t\t\t\t\t\t\t\tonMouseMove={(e) => handlePaperMouseMove(e, i)}\n\t\t\t\t\t\t\t\tonMouseLeave={(e) => handlePaperMouseLeave(e, i)}\n\t\t\t\t\t\t\t\tclassName={`absolute z-20 bottom-[10%] left-1/2 transition-[transform,background-color] duration-300 ease-in-out bg-background ${\n\t\t\t\t\t\t\t\t\t!open\n\t\t\t\t\t\t\t\t\t\t? \"transform -translate-x-1/2 translate-y-[10%] group-hover:translate-y-0\"\n\t\t\t\t\t\t\t\t\t\t: \"hover:scale-110\"\n\t\t\t\t\t\t\t\t} ${sizeClasses}`}\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t...(!open ? {} : { transform: transformStyle }),\n\t\t\t\t\t\t\t\t\tbackgroundColor:\n\t\t\t\t\t\t\t\t\t\ti === 0 ? paper1 : i === 1 ? paper2 : paper3,\n\t\t\t\t\t\t\t\t\tborderRadius: \"10px\",\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{item}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={`absolute z-30 w-full h-full origin-bottom transition-[transform,background-color] duration-300 ease-in-out ${\n\t\t\t\t\t\t\t!open\n\t\t\t\t\t\t\t\t? \"group-hover:transform-[skew(15deg)_scaleY(0.6)]\"\n\t\t\t\t\t\t\t\t: \"\"\n\t\t\t\t\t\t}`}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tbackgroundColor: color,\n\t\t\t\t\t\t\tborderRadius: \"5px 10px 10px 10px\",\n\t\t\t\t\t\t\t...(open && { transform: \"skew(15deg) scaleY(0.6)\" }),\n\t\t\t\t\t\t}}\n\t\t\t\t\t></div>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={`absolute z-30 w-full h-full origin-bottom transition-[transform,background-color] duration-300 ease-in-out ${\n\t\t\t\t\t\t\t!open\n\t\t\t\t\t\t\t\t? \"group-hover:transform-[skew(-15deg)_scaleY(0.6)]\"\n\t\t\t\t\t\t\t\t: \"\"\n\t\t\t\t\t\t}`}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tbackgroundColor: color,\n\t\t\t\t\t\t\tborderRadius: \"5px 10px 10px 10px\",\n\t\t\t\t\t\t\t...(open && { transform: \"skew(-15deg) scaleY(0.6)\" }),\n\t\t\t\t\t\t}}\n\t\t\t\t\t></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n\nexport default Folder;\n",
      "type": "registry:ui"
    }
  ]
}