Customization
Custom UI
Build bespoke upload interfaces using headless hooks and custom components.
Combine @dimah-s3/react hooks with your own components or custom shadcn primitives.
Preview
Example: Headless File Uploader
"use client";
import { useUpload } from "@dimah-s3/react";
import { Button } from "@/components/ui/button";
export function CustomFilePicker() {
const upload = useUpload({ route: "avatar" });
return (
<div className="flex items-center gap-4">
<input {...upload.getInputProps()} />
<Button type="button" onClick={() => upload.open()}>
{upload.isPending
? `Uploading ${upload.progress.percent}%`
: "Choose file"}
</Button>
</div>
);
}Example: A part of your own
Inside Upload, useUploadContext()
returns the root's hook. Build a part that sits next to UploadTrigger and
UploadStatus:
"use client";
import { useUploadContext } from "@dimah-s3/ui";
export function UploadCount() {
const { upload } = useUploadContext();
const done = upload.files.filter((file) => file.phase === "success").length;
if (upload.files.length === 0) return null;
return (
<p className="text-muted-foreground text-sm">
{done} of {upload.files.length} uploaded
</p>
);
}useDownloadContext() and useDeleteContext() do the same inside
Download and Delete.
Frequently asked questions
Read upload.progress for the bytes sent across the queue, and
file.progress for one file:
const { progress, files } = useUpload({ route: "avatar" });
console.log(progress.loaded, progress.total, progress.percent);
console.log(files[0]?.progress.percent);