DocsBlog
  • 0.25.3

  • light

    dark

    system

    Switch mode
  • Cerberus

    Acheron

    Elysium

Get Started
Components
Styling
Theming

Concepts

OverviewCompositionTesting

Layout

Aspect RatioBleedBoxCenterContainerDividerFlexFloatGridLink OverlayScrollableStackWrap

Components

AccordionAdmonitionAvatarButtonCarouselCheckboxClipboardCollapsibleComboboxConfirm ModalCTAModalDate PickerDialogFieldFieldsetFile UploaderIcon ButtonInputLoading StatesMenuNotificationsNumber InputPin 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.

Upload Files

Import any image files

Drag and drop files or click to upload

    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.

    file.txt
    Waiting to upload
    file.txt
    50% Complete
    file.txt
    File uploaded successfully
    file.txt
    There was an error uploading the file
    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
    Cerberus Design System | Docs