file-upload.tsx


Overview

The file-upload.tsx file provides a comprehensive, accessible, and customizable React component library for file uploading functionality. It supports drag-and-drop, file selection dialogs, file validation, progress tracking, and file metadata display. The library is designed with modular components that can be composed together or used individually, enabling flexible integration into React applications.

Key features include:


Components and Utilities

1. FileUploadRoot

Purpose:
The root component that manages the overall file upload state and provides context to child components.

Props:

Prop

Type

Description

value

File[]

Controlled list of files.

defaultValue

File[]

Default files for uncontrolled usage.

onValueChange

(files: File[]) => void

Callback when the controlled file list changes.

onAccept

(files: File[]) => void

Called when files are accepted after validation.

onFileAccept

(file: File) => void

Called for each individual accepted file.

onFileReject

(file: File, message: string) => void

Called for each rejected file with a rejection message.

onFileValidate

[(file: File) => string \

null \

onUpload

[(files: File[], options: { onProgress, onSuccess, onError }) => Promise \

void](/projects/311/72503)

accept

string

Comma-separated list of accepted MIME types or extensions.

maxFiles

number

Maximum number of files allowed.

maxSize

number

Maximum file size in bytes.

dir

`'ltr' \

'rtl'`

label

string

Visually hidden label for input accessibility.

name

string

Name attribute for input.

asChild

boolean

Renders as child component wrapper (uses Radix UI's Slot).

disabled

boolean

Disables the upload functionality.

invalid

boolean

Marks the component as invalid (e.g., validation error).

multiple

boolean

Allows multiple file selection.

required

boolean

Marks the input as required.

Other props

React.ComponentPropsWithoutRef<'div'>

Additional props for the root div element.

Usage Example:

<FileUploadRoot
  accept="image/*"
  maxFiles={5}
  maxSize={5 * 1024 * 1024}
  onUpload={async (files, { onProgress, onSuccess, onError }) => {
    for (const file of files) {
      // simulate upload
      for (let p = 0; p <= 100; p += 10) {
        onProgress(file, p);
        await new Promise(r => setTimeout(r, 100));
      }
      onSuccess(file);
    }
  }}
>
  {/* Dropzone, List, etc. */}
</FileUploadRoot>

2. FileUploadDropzone

Purpose:
Area where users can drag and drop files, click to open file dialog, or paste files from clipboard.

Props:

Prop

Type

Description

asChild

boolean

Render as child component wrapper.

Other props

React.ComponentPropsWithoutRef<'div'>

Props forwarded to the container div.

Features:


3. FileUploadTrigger

Purpose:
A button or custom element that triggers the file selection dialog.

Props:

Prop

Type

Description

asChild

boolean

Render as child component wrapper.

Other props

React.ComponentPropsWithoutRef<'button'>

Props forwarded to the button element.


4. FileUploadList

Purpose:
Renders the list of uploaded files.

Props:

Prop

Type

Description

orientation

`'horizontal' \

'vertical'`

asChild

boolean

Render as child component wrapper.

forceMount

boolean

Forces rendering even if no files are present.


5. FileUploadItem

Purpose:
Represents a single file item in the upload list, including status and accessibility info.

Props:

Prop

Type

Description

value

File

The file instance associated with this item.

asChild

boolean

Render as child component wrapper.


6. FileUploadItemPreview

Purpose:
Renders a preview of the file, either an image thumbnail or a file type icon.

Props:

Prop

Type

Description

render

(file: File) => React.ReactNode

Custom render function to override default preview.

asChild

boolean

Render as child component wrapper.


7. FileUploadItemMetadata

Purpose:
Displays metadata for a file such as name, size, and error message if any.

Props:

Prop

Type

Description

asChild

boolean

Render as child component wrapper.

size

`'default' \

'sm'`


8. FileUploadItemProgress

Purpose:
Displays upload progress for an individual file.

Props:

Prop

Type

Description

variant

`'linear' \

'circular' \

size

number

Size in pixels for circular variant (default 40).

asChild

boolean

Render as child component wrapper.

forceMount

boolean

Render even if progress is 100%.


9. FileUploadItemDelete

Purpose:
Button to remove a file from the upload list.

Props:

Prop

Type

Description

asChild

boolean

Render as child component wrapper.


10. FileUploadClear

Purpose:
Button to clear all files from the upload list.

Props:

Prop

Type

Description

forceMount

boolean

Render even if no files are present.

asChild

boolean

Render as child component wrapper.

disabled

boolean

Explicitly disable button.


Hooks and Utilities

useLazyRef<T>(fn: () => T): React.RefObject<T>

Creates a ref that initializes lazily once.


useDirection(dirProp?: Direction): Direction

Determines text direction ('ltr' or 'rtl') from context or prop.


useStore<T>(selector: (state: StoreState) => T): T

Subscribes to the internal store and selects a slice of the state.


useStoreContext(consumerName: string)

Accesses the internal store context, ensuring it exists.


useFileUploadContext(consumerName: string)

Accesses the file upload context, providing shared IDs, refs, and flags.


formatBytes(bytes: number): string

Formats bytes into human-readable strings (e.g., "1.2 MB").


getFileIcon(file: File): React.ReactNode

Returns an appropriate icon component based on the file's MIME type or extension.


Internal State Management

The file upload uses a custom store implemented with:


File Validation and Upload Workflow

  1. File selection or drag-and-drop triggers onFilesChange.

  2. Files are validated against:

    • Max number of files.

    • Custom validation function.

    • Accepted file types.

    • Max file size.

  3. Accepted files are added to the store; rejected files trigger callbacks.

  4. If an onUpload function is provided, it is called with accepted files and callbacks for progress, success, and error.

  5. Progress updates dispatch store actions to update UI.

  6. Errors and success update file status accordingly.

  7. Users can delete individual files or clear all files.


Interaction with Other Parts of the System


Important Implementation Details


Visual Diagram: Component Structure and Interaction

componentDiagram
    direction LR

    FileUploadRoot <|-- FileUploadDropzone
    FileUploadRoot <|-- FileUploadTrigger
    FileUploadRoot <|-- FileUploadList

    FileUploadList <|-- FileUploadItem

    FileUploadItem <|-- FileUploadItemPreview
    FileUploadItem <|-- FileUploadItemMetadata
    FileUploadItem <|-- FileUploadItemProgress
    FileUploadItem <|-- FileUploadItemDelete

    FileUploadRoot "provides" --> StoreContext
    FileUploadRoot "provides" --> FileUploadContext

    FileUploadDropzone "uses" --> StoreContext
    FileUploadTrigger "uses" --> FileUploadContext
    FileUploadList "uses" --> StoreContext,FileUploadContext
    FileUploadItem "uses" --> StoreContext,FileUploadContext,FileUploadItemContext

    FileUploadItemPreview "uses" --> FileUploadItemContext,FileUploadContext
    FileUploadItemMetadata "uses" --> FileUploadItemContext,FileUploadContext
    FileUploadItemProgress "uses" --> FileUploadItemContext
    FileUploadItemDelete "uses" --> FileUploadItemContext,StoreContext

Summary

The file-upload.tsx file is a robust, accessible React file upload component suite that manages file selection, validation, uploading, and UI feedback via a modular set of components and hooks. It allows detailed customization and integration points for file handling workflows, making it suitable for complex file upload use cases in React applications.