Uplofile is open sourceStar on GitHub

Root

The container component that manages file state and provides context to child components.

Usage

1import { UplofileRoot } from "@/components/ui/uplofile";
2
3export default function RootDemo() {
4 return (
5 <UplofileRoot
6 upload={async (file, signal, onProgress) => {
7 // Implement your upload logic here
8 // e.g., using fetch with FormData
9 return { url: "https://example.com/image.jpg", id: "123" };
10 }}
11 removeMode="optimistic"
12 onRemove={async (item, signal) => {
13 // Optional: implement server-side removal
14 }}
15 onChange={(items) => {
16 console.log("Files changed:", items);
17 }}
18 >
19 {/* Child components */}
20 </UplofileRoot>
21 );
22}

Using Ref for Imperative Control

You can access Root's methods outside the context using a ref. This is useful when you need to use drop handlers or methods from a parent component while maintaining context for children.

The following example demonstrates how to turn a whole parent container into a dropzone by imperatively calling onDrop and onDragOver on the ref.

1import { useRef } from "react";
2import type { DragEvent } from "react";
3import type { UplofileRootRef } from "uplofile";
4import {
5 UplofileDropzone,
6 UplofilePreview,
7 UplofileRoot,
8} from "@/components/ui/uplofile.ts";
9import { mockUpload } from "@/lib/utils.ts";
10
11export default function RootImperativeDemo() {
12 const uplofileRef = useRef<UplofileRootRef>(null);
13
14 // Use ref methods from parent
15 const handleParentDrop = (e: DragEvent) => {
16 uplofileRef.current?.onDrop?.(e);
17 };
18
19 const handleCustomUpdate = () => {
20 // Update items programmatically
21 uplofileRef.current?.setItems((prev) => [...prev]);
22
23 // Or get current items
24 const items = uplofileRef.current?.getItems();
25 };
26
27 let otherProps = {};
28 return (
29 <div
30 className={"flex flex-col items-center justify-center h-full p-5"}
31 onDrop={handleParentDrop}
32 >
33 <UplofileRoot ref={uplofileRef} upload={mockUpload} {...otherProps}>
34 {/* Children still use context normally */}
35 <UplofileDropzone className={"border-2 border-dashed p-8 rounded-lg"} />
36 <UplofilePreview />
37 </UplofileRoot>
38 </div>
39 );
40}

Available ref methods:

  • setItems(items | updater) - Update items state
  • getItems() - Get current items
  • onDrop(e) - Handle drop events
  • onDragOver(e) - Handle drag over events
  • openFileDialog() - Open file picker
  • actions - Access cancel, remove, retry methods

Props

PropTypeDefaultDescription
uploadFunction-Required. Function that handles the file upload. Must return a Promise with { url: string, id?: string }.
multiplebooleantrueWhether to allow multiple file selection
maxCountnumber-Maximum number of files allowed
acceptstring"image/*"Accepted file types (HTML5 input accept attribute)
beforeUploadFunction-Hook to validate or enrich files before upload begins. Supports async validation and per-file granular control.
initialArray[]Pre-hydrated files from server
removeMode"optimistic" | "strict""optimistic"optimistic: UI updates immediately.
strict: UI waits for onRemove to resolve.
onChange(items) => void-Called when the file list changes
onRemove(item, signal) => Promise-Function to handle server-side file deletion
namestring"images"Name used for the hidden input field
disabledbooleanfalseDisable all interactions