{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "folder-contents",
  "title": "Folder contents",
  "description": "Nested folders and documents with independent extraction and rigid-object reveal.",
  "registryDependencies": [
    "@jbm/tokens",
    "@jbm/scene-geometry",
    "@jbm/folder"
  ],
  "files": [
    {
      "path": "registry/jbm/ui/folder-contents.tsx",
      "content": "import type { ComponentProps } from \"react\"\nimport { Folder, FolderOutline } from \"./folder\"\nimport { color, font } from \"../lib/tokens\"\nimport { unit } from \"../lib/geometry\"\n\nexport type FolderEntry = {\n  id: string\n  label: string\n  reveal?: number\n  document?: string\n  documentReveal?: number\n}\n/** A complete fan of nested folders. Reveal translates rigid objects; it never stretches them. */\nexport function FolderContents({\n  entries = [],\n  sheet = \"README.md\",\n  lift = 0,\n  ...props\n}: Omit<ComponentProps<typeof Folder>, \"children\"> & {\n  entries?: FolderEntry[]\n  sheet?: string\n  lift?: number\n}) {\n  const p = unit(props.open ?? 1)\n  return (\n    <Folder {...props} open={p}>\n      <svg\n        x={0}\n        y={p * -36}\n        width={260}\n        height={199 + p * 36}\n        viewBox={`0 ${-p * 36} 260 ${199 + p * 36}`}\n        overflow=\"hidden\"\n      >\n        <g transform={`translate(0 ${-unit(lift) * 240})`}>\n          {entries.map((entry, i) => {\n            const step = entries.length > 1 ? 48 / (entries.length - 1) : 0\n            const top = 24 + i * step\n            const y = 150 - unit(entry.reveal ?? 1) * p * (150 - top)\n            return (\n              <g key={entry.id}>\n                <FolderOutline\n                  x={100}\n                  y={y}\n                  w={125}\n                  h={118}\n                  tabX={108}\n                  tabWidth={78}\n                  fill={color.card}\n                />\n                <text\n                  x={113}\n                  y={y + 12}\n                  fontFamily={font.mono}\n                  fontSize={6.5}\n                  fill={color.ink}\n                >\n                  {entry.label.length > 15\n                    ? `${entry.label.slice(0, 14)}…`\n                    : entry.label}\n                </text>\n                {entry.document && (\n                  <g\n                    transform={`translate(0 ${-unit(entry.documentReveal ?? 0) * p * 45})`}\n                  >\n                    <rect\n                      x={171}\n                      y={y + 31}\n                      width={45}\n                      height={78}\n                      fill={color.card}\n                      stroke={color.ink}\n                      strokeWidth={1.5}\n                    />\n                    <text\n                      x={175}\n                      y={y + 43}\n                      fontFamily={font.mono}\n                      fontSize={5}\n                      fill={color.ink}\n                    >\n                      {entry.document.slice(0, 12)}\n                    </text>\n                    <path\n                      d={`M177 ${y + 53}h31m-31 7h25m-25 7h29`}\n                      stroke={color.line}\n                      strokeWidth={2}\n                    />\n                  </g>\n                )}\n                <path\n                  d={`M100 ${y + 29}H225V${y + 118}H100Z`}\n                  fill={color.accent}\n                  stroke={color.ink}\n                  strokeWidth={1.5}\n                />\n              </g>\n            )\n          })}\n          {sheet && (\n            <g transform={`translate(0 ${(1 - p) * 105})`}>\n              <rect\n                x={35}\n                y={44}\n                width={75}\n                height={110}\n                fill={color.card}\n                stroke={color.ink}\n                strokeWidth={2}\n              />\n              <text\n                x={41}\n                y={59}\n                fontFamily={font.mono}\n                fontSize={7}\n                fill={color.ink}\n              >\n                {sheet.slice(0, 15)}\n              </text>\n              <path d=\"M42 69H98\" stroke={color.accent} strokeWidth={3} />\n              <path\n                d=\"M42 80H99M42 89H90M42 98H96\"\n                stroke={color.line}\n                strokeWidth={2}\n              />\n            </g>\n          )}\n        </g>\n      </svg>\n    </Folder>\n  )\n}\n",
      "type": "registry:ui",
      "target": "src/jbm/ui/folder-contents.tsx"
    }
  ],
  "type": "registry:ui"
}