{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "file-upload-5",
  "title": "Avatar Photo Uploader",
  "description": "Avatar uploader with a circular image preview, change and remove buttons, and a format hint, previewing the picked file via an object URL.",
  "dependencies": [
    "@base-ui/react"
  ],
  "registryDependencies": [
    "button"
  ],
  "files": [
    {
      "path": "registry/blocks/file-upload/5/file-upload-block.tsx",
      "content": "\"use client\"\n\nimport { useRef, useState } from \"react\"\nimport { Button } from \"@/components/ui/button\"\nimport { IconPlaceholder } from \"@/components/icons/icon-placeholder\"\n\nexport default function FileUploadBlock() {\n  const [preview, setPreview] = useState<string | null>(\n    \"https://i.pravatar.cc/160?img=45\"\n  )\n  const inputRef = useRef<HTMLInputElement>(null)\n  // Track the object URL we created so we can release it before replacing it.\n  const objectUrlRef = useRef<string | null>(null)\n\n  function setObjectUrl(url: string | null) {\n    if (objectUrlRef.current) URL.revokeObjectURL(objectUrlRef.current)\n    objectUrlRef.current = url\n    setPreview(url)\n  }\n\n  function handleFile(event: React.ChangeEvent<HTMLInputElement>) {\n    const file = event.target.files?.[0]\n    if (file) setObjectUrl(URL.createObjectURL(file))\n  }\n\n  return (\n    <section className=\"flex w-full items-center justify-center bg-background px-6 py-16 text-foreground\">\n      <div className=\"w-full max-w-sm rounded-xl border border-border bg-card p-6\">\n        <h2 className=\"font-heading text-sm font-semibold tracking-tight\">\n          Profile photo\n        </h2>\n        <p className=\"mt-1 text-xs text-muted-foreground\">\n          This will be shown on your profile and in comments.\n        </p>\n\n        <div className=\"mt-6 flex items-center gap-5\">\n          <span className=\"flex size-20 shrink-0 items-center justify-center overflow-hidden rounded-full border border-border bg-muted\">\n            {preview ? (\n              <img\n                src={preview}\n                alt=\"Avatar preview\"\n                className=\"size-full object-cover grayscale\"\n              />\n            ) : (\n              <IconPlaceholder\n                lucide=\"User\"\n                tabler=\"IconUser\"\n                hugeicons=\"UserIcon\"\n                phosphor=\"User\"\n                remixicon=\"RiUser3Line\"\n                className=\"size-8 text-muted-foreground\"\n                aria-hidden=\"true\"\n              />\n            )}\n          </span>\n\n          <div className=\"flex flex-col gap-2\">\n            <div className=\"flex gap-2\">\n              <Button\n                variant=\"outline\"\n                size=\"sm\"\n                onClick={() => inputRef.current?.click()}\n              >\n                <IconPlaceholder\n                  lucide=\"Upload\"\n                  tabler=\"IconUpload\"\n                  hugeicons=\"UploadIcon\"\n                  phosphor=\"Upload\"\n                  remixicon=\"RiUploadLine\"\n                  data-icon=\"inline-start\"\n                  aria-hidden=\"true\"\n                />\n                Change\n              </Button>\n              {preview && (\n                <Button\n                  variant=\"destructive\"\n                  size=\"sm\"\n                  onClick={() => setObjectUrl(null)}\n                  aria-label=\"Remove photo\"\n                >\n                  <IconPlaceholder\n                    lucide=\"Trash\"\n                    tabler=\"IconTrash\"\n                    hugeicons=\"Delete02Icon\"\n                    phosphor=\"Trash\"\n                    remixicon=\"RiDeleteBinLine\"\n                    className=\"size-4\"\n                    aria-hidden=\"true\"\n                  />\n                </Button>\n              )}\n            </div>\n            <p className=\"text-xs text-muted-foreground\">\n              JPG, PNG or GIF. Max 2&nbsp;MB.\n            </p>\n          </div>\n\n          <input\n            ref={inputRef}\n            type=\"file\"\n            accept=\"image/*\"\n            className=\"hidden\"\n            onChange={handleFile}\n          />\n        </div>\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/blocks/file-upload-5.tsx"
    }
  ],
  "meta": {
    "height": "330px",
    "tier": "free"
  },
  "categories": [
    "file-upload"
  ],
  "type": "registry:block"
}