File Uploadv1.1.2Documentation Under Review
A flexible file upload component with drag-and-drop support, file validation, progress tracking, and customizable trigger coloration built for product applications.
Prefer AI-assisted development?
Catalyst File Upload wraps react-dropzone with a compound-component API and built-in Catalyst design tokens — giving you drag-and-drop, validation, progress tracking, and error recovery with zero boilerplate.
Installation
npm install @pmi/catalyst-file-uploadimport {
FileUploadDropzone,
FileUploadDropzoneArea,
FileUploadTrigger,
FileUploadDescription,
FileUploadMessage,
FileUploadFileList,
FileUploadFileListItem,
FileUploadRemoveFile,
FileUploadRetryFile,
useFileUpload,
useFileUploadFileListContext,
} from '@pmi/catalyst-file-upload';Add the preset to your tailwind.config.ts:
import tailwindFileUploadPreset from '@pmi/catalyst-file-upload';
export default {
presets: [tailwindFileUploadPreset],
// ...
};Variants
Background
Use coloration="background" on FileUploadTrigger to apply a subtle filled background to the dropzone area.
Background Coloration
With background coloration
Neutral
Use coloration="neutral" for a white (light) / dark-surface (dark) dropzone background.
Neutral Coloration
With neutral coloration
Danger
Set isInvalid on FileUploadDropzone to communicate a validation error — the trigger, description, and message all adopt red tones.
Error State
File upload failed
Disabled
Set disabled on FileUploadDropzone to prevent file selection and apply reduced-opacity styles.
Disabled State
Upload functionality is disabled
Common Patterns
Card Wrapper
Wrap the upload component in a Card for elevated visual hierarchy on content-rich pages.
Card Wrapper
Wrapped in a card container
Preview Image
Display uploaded images with aspect-ratio preview thumbnails and per-item progress bars.
Custom variants and composition
Custom default
Use unstyled on all components to remove default CVA classes, then apply your own styles via className or a custom wrapper.
Custom background
Use unstyled on FileUploadTrigger to remove the dashed border, then apply your own background styles.
Background Coloration
With background coloration
Custom Neutral
Use unstyled on FileUploadTrigger to remove the dashed border, then apply your own neutral background styles.
Neutral Coloration
With neutral coloration
Custom Danger
Set isInvalid on FileUploadDropzone to trigger error state, then use unstyled on FileUploadTrigger to remove the dashed border and apply your own error background styles.
Error State
File upload failed
Custom Disabled
Set disabled on FileUploadDropzone to trigger disabled state, then use unstyled on FileUploadTrigger to remove the dashed border and apply your own disabled background styles.
Disabled State
Upload functionality is disabled
Custom card wrapper
Wrap the upload component in a Card for elevated visual hierarchy, then use unstyled on all File Upload components to apply your own styles.
Card Wrapper
Wrapped in a card container
Custom preview image
Display uploaded images with aspect-ratio preview thumbnails and per-item progress bars, then use unstyled on all File Upload components to apply your own styles.
Custom preview image card
Display uploaded images with aspect-ratio preview thumbnails and per-item progress bars, then wrap the upload component in a Card for elevated visual hierarchy and use unstyled on all File Upload components to apply your own styles.
API Reference
File Upload is a compound component built on react-dropzone. The sections below summarize the API surface for each part.
FileUploadDropzone
The root context provider. Spread the return value of useFileUpload onto it and add isInvalid / disabled as needed.
Accepts all props returned by useFileUpload plus children. Forwards that state to all descendant components via context.
FileUploadTrigger
The dashed-border dropzone area. Renders a <label> wrapping a hidden <input type="file">.
Prop
Type
FileUploadDescription
Descriptive helper text displayed below the trigger (accepted types, size limits, etc.).
Accepts all standard <p> HTML attributes. The unstyled prop removes default CVA classes for full className override.
FileUploadMessage
Root-level validation / error message. Reads the dropzone's rootError from context and auto-renders when present.
Prop
Type
FileUploadFileList
Scrollable container for the list of uploaded file items.
Accepts all standard <ul> HTML attributes. The unstyled prop removes default CVA classes.
FileUploadFileListItem
Individual file row. Automatically derives isInvalid from file.status === 'error'.
Prop
Type
FileStatus
Prop
Type
FileUploadRemoveFile
Wrapper for the remove button. Use asChild to render your own Button component inside it.
Accepts all standard <button> HTML attributes plus asChild and unstyled.
FileUploadRetryFile
Wrapper for the retry button on failed uploads. Use asChild to render your own Button component inside it.
Accepts all standard <button> HTML attributes plus asChild and unstyled.
useFileUpload
Hook that wires react-dropzone with Catalyst's file-status reducer. Pass its return value to FileUploadDropzone.
const dropzone = useFileUpload({
onDropFile: async (file: File) => {
return { status: 'success', result: uploadedUrl };
// or on failure:
return { status: 'error', error: 'Upload failed.' };
},
validation: {
accept: { 'image/*': ['.png', '.jpg', '.jpeg'] },
maxSize: 10 * 1024 * 1024,
maxFiles: 10,
},
});Returns fileStatuses, isInvalid, disabled, getInputProps, and other dropzone state.
useFileUploadFileListContext
Access per-item context inside a FileUploadFileListItem for remove / retry callbacks.
Returns onRemoveFile, onRetry, and canRetry.
Accessibility
File Upload is designed to meet WCAG 2.2 AA standards.
Keyboard Interactions
| Key | Action |
|---|---|
Tab | Moves focus to the hidden file input inside the trigger |
Space | Opens the native file picker when the trigger has focus |
Tab | Moves focus through remove / retry buttons in the file list |
Enter | Activates the focused remove or retry button |
ARIA
- The hidden
<input type="file">receivesaria-invalidandaria-describedby(pointing toFileUploadMessage) whenisInvalidis true. FileUploadTriggersetsaria-disabledon the<label>when the dropzone is disabled.ProgressRootin file list items must havearia-labelandaria-valuenowset by the consumer to announce upload progress — see the composition examples above.FileUploadFileMessage(the per-item message element) should be givenclassName="sr-only"when its text is redundant with visible UI, as shown in the default example.- Catalyst adds the visual styling; react-dropzone provides the underlying drag-and-drop and keyboard accessibility semantics.
See the react-dropzone accessibility docs for inherited baseline behavior.
Choosing the Right Component
Use File Upload when users need to select or drop one or more files with progress feedback. Reach for a different primitive when:
| If you need… | Use instead |
|---|---|
| A simple inline text or number input | TextField |
| Rich text or long-form input | TextArea |
| A date or calendar selection | Calendar |
Related
Combobox
A searchable dropdown component that combines an input field with a list of filterable options. Built with Radix UI primitives for robust accessibility.
Radio Group
A set of checkable buttons where no more than one can be checked at a time, providing single-choice selection in forms and interfaces.