• Docs
  • Blog
    • 0.25.1

    • 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.

      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