Upload Button
A button that uploads a single file.
Demo
Installation
npx shadcn@latest add @better-upload/upload-buttonInstall the following dependencies:
npm i lucide-reactAlso add the shadcn/ui button component to your project. As the upload button is built on top of it.
Copy and paste the following code into your project.
import { Button } from '@/components/ui/button';
import type { UploadHookControl } from '@better-upload/client';
import { Loader2, Upload } from 'lucide-react';
import { useId } from 'react';
type UploadButtonProps = {
control: UploadHookControl<false>;
id?: string;
accept?: string;
metadata?: Record<string, unknown>;
uploadOverride?: (
...args: Parameters<UploadHookControl<false>['upload']>
) => void;
// Add any additional props you need.
};
export function UploadButton({
control: { upload, isPending },
id: _id,
accept,
metadata,
uploadOverride,
}: UploadButtonProps) {
const id = useId();
return (
<Button disabled={isPending} className="relative" type="button">
<label htmlFor={_id || id} className="absolute inset-0 cursor-pointer">
<input
id={_id || id}
className="absolute inset-0 size-0 opacity-0"
type="file"
accept={accept}
onChange={(e) => {
if (e.target.files?.[0] && !isPending) {
if (uploadOverride) {
uploadOverride(e.target.files[0], { metadata });
} else {
upload(e.target.files[0], { metadata });
}
}
e.target.value = '';
}}
/>
</label>
{isPending ? (
<>
<Loader2 className="size-4 animate-spin" />
Upload file
</>
) : (
<>
<Upload className="size-4" />
Upload file
</>
)}
</Button>
);
}Update the import paths to match your project setup.
Usage
The <UploadButton /> should be used with the useUploadFile hook.
'use client';
import { useUploadFile } from '@better-upload/client';
import { UploadButton } from '@/components/ui/upload-button';
export function Uploader() {
const { control } = useUploadFile({
route: 'profile',
});
return <UploadButton control={control} accept="image/*" />;
}The button will open a file picker dialog when clicked, and upload the selected file to the desired route.
Props
Prop
Type
Default