All components
Avatar Upload Button
file-uploadOrigin UI component.
responsive · 600px
Install
Same command in any shadcn project — React (Vite/CRA), Next.js, Remix, Astro, and more:
$
npx shadcn@latest add https://your-domain/r/comp-126.jsonUsage
import Cmp from "@/registry/origin-ui/comp-126";
export default function Demo() {
return <Cmp />;
}Component source
"use client";
import { CircleUserRoundIcon, XIcon } from "lucide-react";
import { useFileUpload } from "@/registry/origin-ui/use-file-upload";
import { Button } from "@/components/ui/button";
export default function Component() {
const [{ files }, { removeFile, openFileDialog, getInputProps }] =
useFileUpload({
accept: "image/*",
});
const previewUrl = files[0]?.preview || null;
const fileName = files[0]?.file.name || null;
return (
<div className="flex flex-col items-center gap-2">
<div className="relative inline-flex">
<Button
aria-label={previewUrl ? "Change image" : "Upload image"}
className="relative size-16 overflow-hidden p-0 shadow-none"
onClick={openFileDialog}
variant="outline"
>
{previewUrl ? (
<img
alt="Upload preview"
className="size-full object-cover"
height={64}
src={previewUrl}
style={{ objectFit: "cover" }}
width={64}
/>
) : (
<div aria-hidden="true">
<CircleUserRoundIcon className="size-4 opacity-60" />
</div>
)}
</Button>
{previewUrl && (
<Button
aria-label="Remove image"
className="-top-2 -right-2 absolute size-6 rounded-full border-2 border-background shadow-none focus-visible:border-background"
onClick={() => removeFile(files[0]?.id)}
size="icon"
>
<XIcon className="size-3.5" />
</Button>
)}
<input
{...getInputProps()}
aria-label="Upload image file"
className="sr-only"
tabIndex={-1}
/>
</div>
{fileName && <p className="text-muted-foreground text-xs">{fileName}</p>}
<p
aria-live="polite"
className="mt-2 text-muted-foreground text-xs"
role="region"
>
Avatar upload button
</p>
</div>
);
}Source: Origin UI