{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "dropzone-file-uploader-example",
  "title": "Default File Uploader",
  "description": "The standard visual file uploader built on the headless dropzone primitive.",
  "dependencies": [
    "lucide-react@^0.460.0"
  ],
  "registryDependencies": [
    "@retab/file-uploader"
  ],
  "files": [
    {
      "path": "registry/new-york-v4/blocks/dropzone-file-uploader-example.tsx",
      "content": "\"use client\";\n\nimport { FileUploader } from \"@/components/ui/file-uploader\";\n\nimport { type DropzoneExampleProps } from \"./dropzone-example-shared\";\n\nexport function DefaultFileUploaderExample({\n  className,\n}: DropzoneExampleProps) {\n  return (\n    <section className={className}>\n      <FileUploader\n        accept=\".pdf,.doc,.docx,.xls,.xlsx,.csv,.png,.jpg,.jpeg,application/pdf,image/png,image/jpeg,text/csv\"\n        className=\"min-h-[28rem] justify-start pt-8\"\n        description=\"PDF, DOCX, XLSX, CSV, PNG, or JPG\"\n        maxFiles={6}\n        multiple\n        title=\"Default file uploader\"\n      />\n    </section>\n  );\n}\n",
      "type": "registry:component",
      "target": "@components/blocks/dropzone-file-uploader-example.tsx"
    },
    {
      "path": "registry/new-york-v4/blocks/dropzone-example-shared.tsx",
      "content": "\"use client\";\n\nimport { FileText, X } from \"lucide-react\";\n\nimport type {\n  DropzoneFileItem,\n  DropzoneFileRejection,\n} from \"@/components/ui/dropzone\";\nimport { formatFileSize } from \"@/components/ui/file-size-format\";\n\nexport type DropzoneExampleProps = {\n  className?: string;\n};\n\nexport function InlineFileRows({\n  files,\n  onRemove,\n}: {\n  files: DropzoneFileItem[];\n  onRemove: (fileId: string) => void;\n}) {\n  if (files.length === 0) return null;\n\n  return (\n    <div className=\"mt-3 space-y-1\">\n      {files.map((item) => (\n        <div\n          key={item.id}\n          className=\"bg-background flex min-w-0 items-center gap-2 rounded-md border px-2 py-1.5 text-xs\"\n        >\n          <FileText className=\"text-muted-foreground size-3.5 shrink-0\" />\n          <div className=\"min-w-0 flex-1 truncate\">{item.file.name}</div>\n          <div className=\"text-muted-foreground shrink-0\">\n            {formatFileSize(item.file.size)}\n          </div>\n          <button\n            type=\"button\"\n            aria-label={`Remove ${item.file.name}`}\n            className=\"text-muted-foreground hover:bg-muted hover:text-foreground grid size-5 shrink-0 place-items-center rounded-[4px]\"\n            onClick={() => onRemove(item.id)}\n          >\n            <X className=\"size-3\" aria-hidden />\n          </button>\n        </div>\n      ))}\n    </div>\n  );\n}\n\nexport function RejectionRows({\n  rejections,\n}: {\n  rejections: DropzoneFileRejection[];\n}) {\n  if (rejections.length === 0) return null;\n\n  return (\n    <div className=\"text-destructive mt-3 space-y-1 text-xs\">\n      {rejections.map((rejection) => (\n        <div key={`${rejection.file.name}-${rejection.reason}`}>\n          {rejection.file.name}: {getDropzoneRejectionMessage(rejection)}\n        </div>\n      ))}\n    </div>\n  );\n}\n\nfunction getDropzoneRejectionMessage(rejection: DropzoneFileRejection): string {\n  if (rejection.reason === \"file-invalid-type\") {\n    return \"This file type is not supported here.\";\n  }\n  if (rejection.reason === \"file-too-large\") {\n    return `File must be ${formatFileSize(rejection.maxSize)} or smaller.`;\n  }\n  if (rejection.reason === \"custom\") {\n    return rejection.code;\n  }\n  return rejection.maxFiles === 1\n    ? \"Only one file can be selected.\"\n    : `Only ${rejection.maxFiles} files can be selected.`;\n}\n",
      "type": "registry:file",
      "target": "registry/new-york-v4/blocks/dropzone-example-shared.tsx"
    }
  ],
  "categories": [
    "dropzone"
  ],
  "type": "registry:block"
}