File Upload

Mobile-first file upload with MIME-type and size validation, multi-file selection, error states, and read-only file cards.

import { FileUpload, FileCard, FileCardGroup } from "@plexui/ui/components/FileUpload";

Examples

Overview

With files

  • government-id-scan.pdf
    2.1 MB
  • passport-photo.png
    340 KB
  • non-citizen-travel-2026-approved-document.pdf
    1.5 MB

Error state

  • government-id-scan.pdf
    2.1 MB

Disabled

File Card

Standalone file card component. Wrap with FileCardGroup for the bordered container. Omit onRemove to hide the delete button.

Read-only

project-brief.pdf
2.3 MB

With remove

project-brief.pdf
2.3 MB

Multiple files

government-id-scan.pdf
2.1 MB
passport-photo.png
340 KB
non-citizen-travel-2026-approved-document.pdf
1.5 MB

Read-only list

government-id-scan.pdf
2.1 MB
passport-photo.png
340 KB
non-citizen-travel-2026-approved-document.pdf
1.5 MB

API

PropTypeDefaultDescription
variant"compact" | "area""compact"Visual variant: compact button or larger tappable area
labelstring—Button label text
descriptionstring—Helper text below the icon (area variant only)
acceptstring—Accepted file types (e.g. ".pdf,.png,image/*")
multiplebooleanfalseAllow selecting multiple files. Without it, a new pick replaces the current file
maxFilesnumber—Maximum number of files. Button disables at limit.
maxSizenumber—Maximum file size in bytes
valueFile[]—Controlled file list
onValueChange(files: File[]) => void—Callback when files are added or removed
onFileReject(file: File, reason: string) => void—Callback when a file is rejected (wrong type, too large, over limit)
errorMessagestring—Error message. Sets the invalid visual state
invalidbooleanfalseInvalid state (auto-set when errorMessage is provided)
disabledbooleanfalseDisable all interactions
idstring—Id of the hidden file input
classNamestring—Additional CSS class

Files are picked with the button (or the area); dropping files on it is not supported.

FileCard

PropTypeDefaultDescription
fileFile—The file to display
onRemove() => void—Remove callback. When omitted, the delete button is hidden.
disabledbooleanfalseDisable the remove button
classNamestring—Additional CSS class

FileCardGroup

PropTypeDefaultDescription
childrenReactNode—FileCard elements
classNamestring—Additional CSS class

Styling

File Upload reads these component tokens. Override them at any scope to restyle it:

  • --field-error-margin-top: error margin top (default 0.5rem)
  • --file-upload-area-border-radius: area border radius (default var(--radius-xl))
  • --file-upload-area-min-height: area min height (default 10rem)
  • --file-upload-gutter: gutter (default var(--floating-input-gutter))
  • --file-upload-list-gap: list gap (default 0.5rem)
  • --floating-input-background: background (default var(--color-surface))
  • --floating-input-border-color: border color
  • --floating-input-border-color-hover: border color hover
  • --floating-input-border-color-invalid: border color invalid (default var(--color-border-danger-outline))
  • --floating-input-transition-duration: transition duration (default 80ms)
  • --input-text-color: text color (default var(--color-text))