DocsBlog
  • 1.0.0

  • light

    dark

    system

    Switch mode
  • Cerberus

    Acheron

    Elysium

Get Started
Components
Data Grid
Styling
Theming

Concepts

OverviewCompositionCerberus ContextTesting

Layout

Aspect RatioBleedBoxCenterContainerDividerFlexFloatGridGroupNewLink OverlayScrollableStackWrap

Components

AccordionAdmonitionAvatarButtonCarouselCheckboxClipboardCollapsibleComboboxConfirm ModalCTAModalDate PickerDialogFieldFieldsetFile UploaderIcon ButtonInputLoading StatesMenuNotificationsNumber InputPaginationNewPin InputProgressPrompt ModalRadioRatingSelectSplit ButtonSwitchTableTabsTagTextTextareaToggleTooltip

Utilities

Client OnlyDownload TriggerEnvironmentFeature FlagsFocus TrapForFormat ByteFormat NumberFormat Relative TimeFrameHighlightJSON Tree ViewLocaleLocal StoragePortalPresenceShowsplitPropsTheme

File Uploader

A component to allow users to upload files and display their status.

  • npm
  • source
  • recipe
  • Ark
import { FileUploader, FileStatus, processStatus } from '@cerberus/react'

Uploading Files

To allow users to upload files, use the FileUploader component. This will provide a drag-and-drop area for users to upload files which is also clickable.

Once a valid file is added, a preview card of the file will be displayed.

Copy
img-uploader.tsx
import { FileUploader } from '@cerberus/react'
export function BasicFileUploader() {
return (
<FileUploader
accept="image/*"
heading="Upload Files"
name="basic-example"
/>
)
}

File Status

If you choose to process the file, you can use the FileStatus component to display the status of the job.

Copy
file-status.tsx
'use client'
import {
FileStatus,
type FileStatusActions,
processStatus,
} from '@cerberus/react'
import { vstack } from 'styled-system/patterns'
import { useCallback, type MouseEvent } from 'react'
export function UploadingCardsPreview() {
const handleClick = useCallback(
(status: FileStatusActions, e: MouseEvent<HTMLButtonElement>) =>
console.log(status, e),
[],
)
return (
<div
className={vstack({
maxW: '36rem',
w: '3/4',
})}
>
<FileStatus
id="todo"
file="file.txt"
now={0}
onClick={handleClick}
status={processStatus.TODO}
/>
<FileStatus
id="processing"
file="file.txt"
now={50}
onClick={handleClick}
status={processStatus.PROCESSING}
/>
<FileStatus
id="done"
file="file.txt"
now={100}
onClick={handleClick}
status={processStatus.DONE}
/>
<FileStatus
id="error"
file="file.txt"
now={0}
onClick={handleClick}
status={processStatus.ERROR}
/>
</div>
)
}

Accepted File Types

Use the accept prop to restrict the file types that can be uploaded. This prop accepts MIME types (e.g., image/png, image/jpeg) or file extensions (e.g., .pdf, .txt).

When users attempt to upload files that don't match the accepted types, these files will be automatically rejected and appear in the rejectedFiles array with a FILE_INVALID_TYPE error code.

import { FileUploader } from '@cerberus-design/react';
<FileUploader
id="file-uploader"
accept="image/png, image/jpeg"
/>

Error Handling

The FileUploader component provides comprehensive validation and error handling capabilities. You can set various constraints and handle different types of validation errors:

Built-in Validation Props:

  • maxFiles - Maximum number of files allowed
  • maxFileSize - Maximum file size in bytes
  • minFileSize - Minimum file size in bytes
  • accept - Allowed MIME types or file extensions

Built-in Error Types:

  • TOO_MANY_FILES - Exceeds maxFiles limit
  • FILE_INVALID_TYPE - File type not in accept list
  • FILE_TOO_LARGE - File size exceeds maxFileSize
  • FILE_TOO_SMALL - File size below minFileSize
  • FILE_INVALID - Generic validation failure
  • FILE_EXISTS - Duplicate file detected
import {
FileUploader,
FileUploadParts,
createErrorMessages,
Text,
} from '@cerberus/react'
const errorMessages = createErrorMessages({
TOO_MANY_FILES: '📊 Too many files selected (max 3 allowed)',
FILE_INVALID_TYPE: '🚫 Invalid file type (only images and PDFs allowed)',
FILE_TOO_LARGE: '📏 File too large (max 1MB)',
FILE_TOO_SMALL: '📐 File too small (min 1KB)',
FILE_INVALID: '⚠️ Invalid file',
FILE_EXISTS: '🔄 File already exists',
})
export const ErrorHandling = () => {
return (
<FileUploader
maxFiles={3}
maxFileSize={1024 * 1024} // 1MB
minFileSize={1024} // 1KB
accept="image/*,application/pdf"
showPreview={false}
>
<div data-status="rejected">
<Text textStyle="heading-md">❌ Rejected Files</Text>
<FileUploadParts.ItemGroup>
<FileUploadParts.Context>
{({ rejectedFiles }) =>
rejectedFiles.length === 0 ? (
<Text>No rejected files</Text>
) : (
rejectedFiles.map((fileRejection) => (
<FileUploadParts.Item
key={fileRejection.file.name}
file={fileRejection.file}
data-status="rejected"
>
<FileUploadParts.ItemName />
<FileUploadParts.ItemSizeText />
<div>
<Text as="strong">Validation Errors:</Text>
{fileRejection.errors.map((error, index) => (
<div key={index} data-error-code={error}>
{errorMessages[error as FileUploadFileError] || `❓ ${error}`}
</div>
))}
</div>
</FileUploadParts.Item>
))
)
}
</FileUploadParts.Context>
</FileUploadParts.ItemGroup>
</div>
</FileUploader>
)
}

Error Helpers

To easily create error messages for the built-in error types, use the createErrorMessages function:

createErrorMessages({
tooMany: 'Too many files were selected',
invalidType: 'This is not a valid file type',
tooLarge: 'File size exceeds the maximum allowed (3KB)',
tooSmall: 'File size must be at least 1KB',
invalid: 'File type is not supported. Please select a valid file type.',
exists: 'File already exists'
})

All of the properties within the options Object are optional and will provide the following default error messages if not provided:

{
TOO_MANY_FILES: options.tooMany || '📊 Too many files selected',
FILE_INVALID_TYPE: options.invalidType || '🚫 Invalid file type',
FILE_TOO_LARGE: options.tooLarge || '📏 File too large',
FILE_TOO_SMALL: options.tooSmall || '📐 File too small',
FILE_INVALID: options.invalid || '⚠️ Invalid file',
FILE_EXISTS: options.exists || '🔄 File already exists',
}

File Transformations

Use the transformFiles prop to process files before they're added to the accepted files list. This is useful for file compression, format conversion, or adding metadata.

Common transformation use cases:

  • Image compression: Use image-conversion, browser-image-compression, or similar libraries
  • Format conversion: Convert files to different formats (e.g., HEIC to JPEG)
  • Metadata extraction: Add EXIF data or other file information
  • File validation: Perform additional checks beyond basic validation
  • Resizing: Automatically resize images to specific dimensions
import { FileUploader } from '@cerberus/react/file-upload'
import { compressAccurately } from 'image-conversion'
function FileTransformationsDemo() {
const transformFiles = async (files: File[]) => {
return Promise.all(
files.map(async (file) => {
if (file.type.startsWith('image/')) {
try {
// Compress image to ~200KB
const blob = await compressAccurately(file, 200)
return new File([blob], file.name, { type: blob.type })
} catch (error) {
console.error('Compression failed for:', file.name, error)
return file
}
}
return file // Return non-image files as-is
}),
)
}
return (
<FileUploader
accept="image/*"
maxFiles={5}
transformFiles={transformFiles}
/>
)
}

Custom Validation

Use the validate prop to implement custom validation logic beyond the built-in constraints.

<FileUploadParts.Root
validate={(file) => {
if (file.name.length > 20) return ['FILE_NAME_TOO_LONG']
return null
}}
/>

Guides

File Previews

The FileUpload component provides flexible preview options for different file types. Use ItemPreview with type matching to show appropriate previews based on file format.

Preview Types:

  • type="image/*": Shows image thumbnails using ItemPreviewImage
  • type="video/*": For video file previews
  • type="application/pdf": For PDF files
  • type=".*": Generic fallback for any file type
<FileUploadParts.ItemPreview type="image/*">
<FileUploadParts.ItemPreviewImage />
</FileUploadParts.ItemPreview>
<FileUploadParts.ItemPreview type="video/*">
<VideoIcon />
</FileUploadParts.ItemPreview>
<FileUploadParts.ItemPreview type="application/pdf">
<PdfIcon />
</FileUploadParts.ItemPreview>
<FileUploadParts.ItemPreview type=".*">
<FileIcon />
</FileUploadParts.ItemPreview>

File Metadata Display:

  • ItemName - Shows the file name
  • ItemSizeText - Shows formatted file size (e.g., "2.5 MB")

Disable dropzone

To disable drag-and-drop functionality, set the allowDrop prop to false.

<FileUploader allowDrop={false} />

Prevent document drop

By default, when the dropzone is active, we prevent accidental navigation when files are dropped outside the dropzone. To prevent this behavior, set the preventDocumentDrop prop to false.

<FileUploader preventDocumentDrop={false} />

Prevent double open

When you want to delegate clicking to the trigger and remove the dropzone from the tab order, you can use the disableClick prop. This prevents the the file picker from opening twice.

<FileUploadParts.Dropzone disableClick>
<FileUploadParts.Trigger>Choose Files</FileUploadParts.Trigger>
Drag files here
</FileUploadParts.Dropzone>

Primitives

You can utilize the primitive components or the style props to customize the file uploader.

ComponentDescription
FileUploadRootThe context provider for the FileUploader parts
FileUploadTriggerThe trigger of the FileUploader
FileUploadDropzoneThe dropzone of the FileUploader
FileUploadLabelThe label of the FileUploader
FileUploadTriggerThe trigger of the FileUploader
FileUploadClearTriggerThe clear trigger of the FileUploader
FileUPloadItemGroupThe container for the group of items
FileUploadItemThe container for the item
FileUploadItemPreviewThe container of hte preview for the item
FileUploadItemPreviewImageThe image preview for the item
FileUploadItemNameThe name of the item
FileUploadItemSizeTextThe size text of the item
FileUploadItemDeleteTriggerThe delete trigger of the FileUploader
FileUPloadHiddenInputThe hidden input of the FileUploader
FileUploadContextThe context of the FileUploader
FileUploadIconThe icon of the FileUploader
FileUploadHeadingThe heading of the FileUploader
FileUploadDescriptionThe description of the FileUploader

API

FileUploader

PropTypeDescription
acceptRecord<string, string[]>The accept file types
acceptedFilesFile[]The controlled accepted files
allowDropbooleanWhether to allow drag and drop in the dropzone element
asChildbooleanUse the provided child element as the default rendered element, combining their props and behavior.
capture'user' or 'environment'The default camera to use when capturing media
defaultAcceptedFilesFile[]The default accepted files when rendered. Use when you don't need to control the accepted files of the input.
directorybooleanWhether to accept directories, only works in webkit browsers
disabledbooleanWhether the file input is disabled
idsPartial<PrimitiveStack>The ids of the elements. Useful for composition.
invalidbooleanWhether the file input is invalid
localestringThe current locale. Based on the BCP 47 definition.
maxFilesnumberThe maximum number of files
maxFileSizenumberThe maximum file size in bytes
minFileSizenumberThe minimum file size in bytes
namestringThe name of the underlying file input
onFileAccept(details: FileAcceptDetails) => voidFunction called when the file is accepted
onFileChange(details: FileChangeDetails) => voidFunction called when the value changes, whether accepted or rejected
onFileReject(details: FileRejectDetails) => voidFunction called when the file is rejected
preventDocumentDropbooleanWhether to prevent the drop event on the document
requiredbooleanWhether the file input is required
transformFiles(files: File[]) => Promise<File[]>Function to transform the accepted files to apply transformations
translationsIntlTranslationsThe localized messages to use.
validate(file: File, details: FileValidateDetails) => FileError[] or nullFunction to validate a file
headingstringThe heading for the file uploader
showPreviewbooleanWhether to show the preview of the file or custom children.

Root Data Attributes:

AttributeValue
[data-scope]file-upload
[data-part]root
[data-disabled]Present when disabled
[data-dragging]Present when in the dragging state

FileStatus

The FileStatus component accepts the following props:

NameDefaultDescription
idA unique identifier for the ProgressBar.
fileThe name of the file being processed
nowThe current progress of the file upload
status'todo'The status of the file upload

On this page

  • Edit this page on Github

Upload Files

Import any image files

Drag and drop files or click to upload

    file.txt
    Waiting to upload
    file.txt
    50% Complete
    file.txt
    File uploaded successfully
    file.txt
    There was an error uploading the file
    Cerberus Design System | Docs