File Input

1.22.0Beta

The File Input component renders a single-file form field with QDS input styling and file validation support.

import {FileInput} from "@qualcomm-ui/react/file-input"

Overview

The File Input component supports both click-to-browse and drag-and-drop interactions for a single file input. An advanced file upload component is currently in development and will support multi-file lists, async uploads, previews, and rejected-file workflows.

Examples

Simple

The simple <FileInput> bundles all subcomponents together into a single component.

Select a file
<FileInput
  className="w-full max-w-sm"
  label="Upload file"
  placeholder="Select a file"
  startIcon={Upload}
/>

Composite

Use the composite API for explicit control over layout or part props.

Select a PDF
<FileInput.Root
  accept={[".pdf"]}
  className="w-full max-w-sm"
  startIcon={Upload}
>
  <FileInput.Label>Upload agreement</FileInput.Label>
  <FileInput.Control>
    <FileInput.Display placeholder="Select a PDF" />
  </FileInput.Control>
  <FileInput.HiddenInput />
</FileInput.Root>

Sizes

The File Input component supports three size variants: sm, md (default), and lg.

Select a file
Select a file
Select a file
<div className="flex w-full flex-col items-center gap-6">
  <FileInput
    className="w-full max-w-sm"
    label="Upload file (Small)"
    placeholder="Select a file"
    size="sm"
    startIcon={Upload}
  />

  <FileInput
    className="w-full max-w-sm"
    label="Upload file (Medium)"
    placeholder="Select a file"
    size="md"
    startIcon={Upload}
  />

  <FileInput
    className="w-full max-w-sm"
    label="Upload file (Large)"
    placeholder="Select a file"
    size="lg"
    startIcon={Upload}
  />
</div>

Errors

Set invalid and errorText for field-level validation messages. File validation is configured with props such as accept, maxFileSize, and validate.

Select a PDF
Upload a PDF file under 5 MB
<FileInput
  accept={[".pdf"]}
  className="w-full max-w-sm"
  errorText="Upload a PDF file under 5 MB"
  invalid
  label="Tax document"
  maxFileSize={5 * 1024 * 1024}
  placeholder="Select a PDF"
  required
  startIcon={Upload}
/>

Disabled

Set disabled on the root or simple component.

Select a file
<div className="flex w-full max-w-sm flex-col gap-4">
  <Checkbox
    checked={agreed}
    label="I agree to the terms and conditions"
    onCheckedChange={setAgreed}
  />
  <FileInput
    disabled={!agreed}
    label="Upload approval"
    placeholder="Select a file"
    startIcon={Upload}
  />
</div>

API

<FileInput />

The FileInput extends FileInput.Root with the following props:

PropTypeDefault
The simple FileInput doesn't support children.
never
When true, renders a clear button that resets the selected file on click. The button only appears when a file has been selected.
boolean
true
{
render?:
| Element
| ((
props: Props,
) => Element)
}
Props applied to the visible input-like control.
{
children?: ReactNode
render?:
| Element
| ((
props: Props,
) => Element)
}
Props applied to the selected file name display.
{
placeholder?: ReactNode
render?:
| Element
| ((
props: Props,
) => Element)
}
Optional error message that describes the element when invalid is true.
Props applied to the error text element.
{
children?: ReactNode
icon?:
| LucideIcon
| ReactNode
render?:
| Element
| ((
props: Props,
) => Element)
}
Props applied to the hidden file input element.
{
render?:
| Element
| ((
props: Props,
) => Element)
}
Optional label describing the file input. This element is automatically associated with the hidden file input for accessibility.
Props applied to the label element.
{
children?: ReactNode
render?:
| Element
| ((
props: Props,
) => Element)
}
Text shown when no file has been selected.
Type
never
Description
The simple FileInput doesn't support children.
Type
boolean
Description
When true, renders a clear button that resets the selected file on click. The button only appears when a file has been selected.
Type
{
render?:
| Element
| ((
props: Props,
) => Element)
}
Type
{
children?: ReactNode
render?:
| Element
| ((
props: Props,
) => Element)
}
Description
Props applied to the visible input-like control.
Type
{
placeholder?: ReactNode
render?:
| Element
| ((
props: Props,
) => Element)
}
Description
Props applied to the selected file name display.
Description
Optional error message that describes the element when invalid is true.
Type
{
children?: ReactNode
icon?:
| LucideIcon
| ReactNode
render?:
| Element
| ((
props: Props,
) => Element)
}
Description
Props applied to the error text element.
Type
{
render?:
| Element
| ((
props: Props,
) => Element)
}
Description
Props applied to the hidden file input element.
Description
Optional label describing the file input. This element is automatically associated with the hidden file input for accessibility.
Type
{
children?: ReactNode
render?:
| Element
| ((
props: Props,
) => Element)
}
Description
Props applied to the label element.
Description
Text shown when no file has been selected.

Composite API

<FileInput.Root>

PropTypeDefault
Accepted file types (e.g., ['image/*', '.pdf']). Supports MIME types, file extensions, or custom validation.
| Record<string, string[]>
| 'image/png'
| 'image/gif'
| 'image/jpeg'
| 'image/svg+xml'
| 'image/webp'
| 'image/avif'
| 'image/heic'
| 'image/bmp'
| 'application/pdf'
| 'application/zip'
| 'application/json'
| 'application/xml'
| 'application/msword'
| 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
| 'application/vnd.ms-excel'
| 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
| 'application/vnd.ms-powerpoint'
| 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
| 'application/rtf'
| 'application/x-rar'
| 'application/x-7z-compressed'
| 'application/x-tar'
| 'application/vnd.microsoft.portable-executable'
| 'text/css'
| 'text/csv'
| 'text/html'
| 'text/markdown'
| 'text/plain'
| 'font/ttf'
| 'font/otf'
| 'font/woff'
| 'font/woff2'
| 'font/eot'
| 'font/svg'
| 'video/mp4'
| 'video/webm'
| 'video/ogg'
| 'video/quicktime'
| 'video/x-msvideo'
| 'audio/mpeg'
| 'audio/ogg'
| 'audio/wav'
| 'audio/webm'
| 'audio/aac'
| 'audio/flac'
| 'audio/x-m4a'
| 'image/*'
| 'audio/*'
| 'video/*'
| 'text/*'
| 'application/*'
| 'font/*'
| AnyString
| Array<
| 'image/png'
| 'image/gif'
| 'image/jpeg'
| 'image/svg+xml'
| 'image/webp'
| 'image/avif'
| 'image/heic'
| 'image/bmp'
| 'application/pdf'
| 'application/zip'
| 'application/json'
| 'application/xml'
| 'application/msword'
| 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
| 'application/vnd.ms-excel'
| 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
| 'application/vnd.ms-powerpoint'
| 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
| 'application/rtf'
| 'application/x-rar'
| 'application/x-7z-compressed'
| 'application/x-tar'
| 'application/vnd.microsoft.portable-executable'
| 'text/css'
| 'text/csv'
| 'text/html'
| 'text/markdown'
| 'text/plain'
| 'font/ttf'
| 'font/otf'
| 'font/woff'
| 'font/woff2'
| 'font/eot'
| 'font/svg'
| 'video/mp4'
| 'video/webm'
| 'video/ogg'
| 'video/quicktime'
| 'video/x-msvideo'
| 'audio/mpeg'
| 'audio/ogg'
| 'audio/wav'
| 'audio/webm'
| 'audio/aac'
| 'audio/flac'
| 'audio/x-m4a'
| 'image/*'
| 'audio/*'
| 'video/*'
| 'text/*'
| 'application/*'
| 'font/*'
| AnyString
>
Controlled accepted files. Use with onFileChange for controlled state.
Array<File>
Whether to allow drag and drop in the dropzone.
boolean
true
Default camera for capturing media on mobile devices.
| 'user'
| 'environment'
The default accepted files when rendered. Use when you don't need to control the accepted files of the input.
Array<File>
The document's text/writing direction.
'ltr' | 'rtl'
'ltr'
Whether to accept directories. Only supported in webkit browsers.
boolean
Whether the file input is disabled
boolean
lucide icon, positioned at the end of the input field.
| LucideIcon
| ReactNode
A root node to correctly resolve document in custom environments. i.e., Iframes, Electron.
    () =>
    | Node
    | ShadowRoot
    | Document
    The ids of the elements. Useful for composition.
    Partial<{
    dropzone: string
    errorText: string
    hiddenInput: string
    item: string[]
    itemName: string[]
    itemPreview: string[]
    itemSizeText: string[]
    label: string
    root: string
    trigger: string
    }>
    Whether the file input is invalid. When true, applies error styling and shows the error text. Use for form-level validation. Per-file rejection errors are handled automatically.
    boolean
    The current locale. Based on the BCP 47 definition.
    string
    'en-US'
    
    The maximum number of files
    number
    1
    
    Maximum file size in bytes.
    number
    Infinity
    
    Minimum file size in bytes.
    number
    0
    
    Name attribute for the underlying file input.
    string
    Function called when the file is accepted
      (details: {
      files: Array<File>
      }) => void
      Function called when the value changes, whether accepted or rejected
        (details: {
        acceptedFiles: Array<File>
        rejectedFiles: Array<{
        errors: Array<
        | 'TOO_MANY_FILES'
        | 'FILE_INVALID_TYPE'
        | 'FILE_TOO_LARGE'
        | 'FILE_TOO_SMALL'
        | 'FILE_INVALID'
        | 'FILE_EXISTS'
        | AnyString
        >
        file: File
        }>
        }) => void
        Function called when the file is rejected
          (details: {
          files: Array<{
          errors: Array<
          | 'TOO_MANY_FILES'
          | 'FILE_INVALID_TYPE'
          | 'FILE_TOO_LARGE'
          | 'FILE_TOO_SMALL'
          | 'FILE_INVALID'
          | 'FILE_EXISTS'
          | AnyString
          >
          file: File
          }>
          }) => void
          Whether to prevent dropping files outside the dropzone.
          boolean
          true
          
          Allows you to replace the component's HTML element with a different tag or component. Learn more
          | ReactElement
          | ((
          props: object,
          ) => ReactElement)
          Whether the file input is required
          boolean
          The size of the input field and its elements. Governs properties like font size, item padding, and icon sizes.
          | 'sm'
          | 'md'
          | 'lg'
          'md'
          
          lucide icon, positioned at the start of the input field.
          | LucideIcon
          | ReactNode
          Transforms accepted files asynchronously after validation. Use for compression, resizing, format conversion, or other processing before setting final state.
            (
            files: Array<File>,
            ) => Promise<Array<File>>
            Localized messages for accessibility labels.
            {
            listLabel?: string
            }
            Function to validate a file
              (
              file: File,
              details: {
              acceptedFiles: Array<File>
              rejectedFiles: Array<{
              errors: Array<
              | 'TOO_MANY_FILES'
              | 'FILE_INVALID_TYPE'
              | 'FILE_TOO_LARGE'
              | 'FILE_TOO_SMALL'
              | 'FILE_INVALID'
              | 'FILE_EXISTS'
              | AnyString
              >
              file: File
              }>
              },
              ) => Array<
              | 'TOO_MANY_FILES'
              | 'FILE_INVALID_TYPE'
              | 'FILE_TOO_LARGE'
              | 'FILE_TOO_SMALL'
              | 'FILE_INVALID'
              | 'FILE_EXISTS'
              | AnyString
              >
              Type
              | Record<string, string[]>
              | 'image/png'
              | 'image/gif'
              | 'image/jpeg'
              | 'image/svg+xml'
              | 'image/webp'
              | 'image/avif'
              | 'image/heic'
              | 'image/bmp'
              | 'application/pdf'
              | 'application/zip'
              | 'application/json'
              | 'application/xml'
              | 'application/msword'
              | 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
              | 'application/vnd.ms-excel'
              | 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
              | 'application/vnd.ms-powerpoint'
              | 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
              | 'application/rtf'
              | 'application/x-rar'
              | 'application/x-7z-compressed'
              | 'application/x-tar'
              | 'application/vnd.microsoft.portable-executable'
              | 'text/css'
              | 'text/csv'
              | 'text/html'
              | 'text/markdown'
              | 'text/plain'
              | 'font/ttf'
              | 'font/otf'
              | 'font/woff'
              | 'font/woff2'
              | 'font/eot'
              | 'font/svg'
              | 'video/mp4'
              | 'video/webm'
              | 'video/ogg'
              | 'video/quicktime'
              | 'video/x-msvideo'
              | 'audio/mpeg'
              | 'audio/ogg'
              | 'audio/wav'
              | 'audio/webm'
              | 'audio/aac'
              | 'audio/flac'
              | 'audio/x-m4a'
              | 'image/*'
              | 'audio/*'
              | 'video/*'
              | 'text/*'
              | 'application/*'
              | 'font/*'
              | AnyString
              | Array<
              | 'image/png'
              | 'image/gif'
              | 'image/jpeg'
              | 'image/svg+xml'
              | 'image/webp'
              | 'image/avif'
              | 'image/heic'
              | 'image/bmp'
              | 'application/pdf'
              | 'application/zip'
              | 'application/json'
              | 'application/xml'
              | 'application/msword'
              | 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
              | 'application/vnd.ms-excel'
              | 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
              | 'application/vnd.ms-powerpoint'
              | 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
              | 'application/rtf'
              | 'application/x-rar'
              | 'application/x-7z-compressed'
              | 'application/x-tar'
              | 'application/vnd.microsoft.portable-executable'
              | 'text/css'
              | 'text/csv'
              | 'text/html'
              | 'text/markdown'
              | 'text/plain'
              | 'font/ttf'
              | 'font/otf'
              | 'font/woff'
              | 'font/woff2'
              | 'font/eot'
              | 'font/svg'
              | 'video/mp4'
              | 'video/webm'
              | 'video/ogg'
              | 'video/quicktime'
              | 'video/x-msvideo'
              | 'audio/mpeg'
              | 'audio/ogg'
              | 'audio/wav'
              | 'audio/webm'
              | 'audio/aac'
              | 'audio/flac'
              | 'audio/x-m4a'
              | 'image/*'
              | 'audio/*'
              | 'video/*'
              | 'text/*'
              | 'application/*'
              | 'font/*'
              | AnyString
              >
              Description
              Accepted file types (e.g., ['image/*', '.pdf']). Supports MIME types, file extensions, or custom validation.
              Type
              Array<File>
              Description
              Controlled accepted files. Use with onFileChange for controlled state.
              Type
              boolean
              Description
              Whether to allow drag and drop in the dropzone.
              Type
              | 'user'
              | 'environment'
              Description
              Default camera for capturing media on mobile devices.
              Type
              Array<File>
              Description
              The default accepted files when rendered. Use when you don't need to control the accepted files of the input.
              Type
              'ltr' | 'rtl'
              Description
              The document's text/writing direction.
              Type
              boolean
              Description
              Whether to accept directories. Only supported in webkit browsers.
              Type
              boolean
              Description
              Whether the file input is disabled
              Type
              | LucideIcon
              | ReactNode
              Description
              lucide icon, positioned at the end of the input field.
              Type
              () =>
              | Node
              | ShadowRoot
              | Document
              Description
              A root node to correctly resolve document in custom environments. i.e., Iframes, Electron.
                Type
                Partial<{
                dropzone: string
                errorText: string
                hiddenInput: string
                item: string[]
                itemName: string[]
                itemPreview: string[]
                itemSizeText: string[]
                label: string
                root: string
                trigger: string
                }>
                Description
                The ids of the elements. Useful for composition.
                Type
                boolean
                Description
                Whether the file input is invalid. When true, applies error styling and shows the error text. Use for form-level validation. Per-file rejection errors are handled automatically.
                Type
                string
                Description
                The current locale. Based on the BCP 47 definition.
                Type
                number
                Description
                The maximum number of files
                Type
                number
                Description
                Maximum file size in bytes.
                Type
                number
                Description
                Minimum file size in bytes.
                Type
                string
                Description
                Name attribute for the underlying file input.
                Type
                (details: {
                files: Array<File>
                }) => void
                Description
                Function called when the file is accepted
                  Type
                  (details: {
                  acceptedFiles: Array<File>
                  rejectedFiles: Array<{
                  errors: Array<
                  | 'TOO_MANY_FILES'
                  | 'FILE_INVALID_TYPE'
                  | 'FILE_TOO_LARGE'
                  | 'FILE_TOO_SMALL'
                  | 'FILE_INVALID'
                  | 'FILE_EXISTS'
                  | AnyString
                  >
                  file: File
                  }>
                  }) => void
                  Description
                  Function called when the value changes, whether accepted or rejected
                    Type
                    (details: {
                    files: Array<{
                    errors: Array<
                    | 'TOO_MANY_FILES'
                    | 'FILE_INVALID_TYPE'
                    | 'FILE_TOO_LARGE'
                    | 'FILE_TOO_SMALL'
                    | 'FILE_INVALID'
                    | 'FILE_EXISTS'
                    | AnyString
                    >
                    file: File
                    }>
                    }) => void
                    Description
                    Function called when the file is rejected
                      Type
                      boolean
                      Description
                      Whether to prevent dropping files outside the dropzone.
                      Type
                      | ReactElement
                      | ((
                      props: object,
                      ) => ReactElement)
                      Description
                      Allows you to replace the component's HTML element with a different tag or component. Learn more
                      Type
                      boolean
                      Description
                      Whether the file input is required
                      Type
                      | 'sm'
                      | 'md'
                      | 'lg'
                      Description
                      The size of the input field and its elements. Governs properties like font size, item padding, and icon sizes.
                      Type
                      | LucideIcon
                      | ReactNode
                      Description
                      lucide icon, positioned at the start of the input field.
                      Type
                      (
                      files: Array<File>,
                      ) => Promise<Array<File>>
                      Description
                      Transforms accepted files asynchronously after validation. Use for compression, resizing, format conversion, or other processing before setting final state.
                        Type
                        {
                        listLabel?: string
                        }
                        Description
                        Localized messages for accessibility labels.
                        Type
                        (
                        file: File,
                        details: {
                        acceptedFiles: Array<File>
                        rejectedFiles: Array<{
                        errors: Array<
                        | 'TOO_MANY_FILES'
                        | 'FILE_INVALID_TYPE'
                        | 'FILE_TOO_LARGE'
                        | 'FILE_TOO_SMALL'
                        | 'FILE_INVALID'
                        | 'FILE_EXISTS'
                        | AnyString
                        >
                        file: File
                        }>
                        },
                        ) => Array<
                        | 'TOO_MANY_FILES'
                        | 'FILE_INVALID_TYPE'
                        | 'FILE_TOO_LARGE'
                        | 'FILE_TOO_SMALL'
                        | 'FILE_INVALID'
                        | 'FILE_EXISTS'
                        | AnyString
                        >
                        Description
                        Function to validate a file

                          <FileInput.Label>

                          PropType
                          Allows you to replace the component's HTML element with a different tag or component. Learn more
                          | ReactElement
                          | ((
                          props: object,
                          ) => ReactElement)
                          Type
                          | ReactElement
                          | ((
                          props: object,
                          ) => ReactElement)
                          Description
                          Allows you to replace the component's HTML element with a different tag or component. Learn more

                          <FileInput.Control>

                          PropType
                          React children prop.
                          Allows you to replace the component's HTML element with a different tag or component. Learn more
                          | ReactElement
                          | ((
                          props: object,
                          ) => ReactElement)
                          Description
                          React children prop.
                          Type
                          | ReactElement
                          | ((
                          props: object,
                          ) => ReactElement)
                          Description
                          Allows you to replace the component's HTML element with a different tag or component. Learn more

                          <FileInput.ClearTrigger>

                          PropType
                          Allows you to replace the component's HTML element with a different tag or component. Learn more
                          | ReactElement
                          | ((
                          props: object,
                          ) => ReactElement)
                          Type
                          | ReactElement
                          | ((
                          props: object,
                          ) => ReactElement)
                          Description
                          Allows you to replace the component's HTML element with a different tag or component. Learn more

                          <FileInput.Display>

                          PropType
                          Text shown when no file has been selected.
                          Allows you to replace the component's HTML element with a different tag or component. Learn more
                          | ReactElement
                          | ((
                          props: object,
                          ) => ReactElement)
                          Description
                          Text shown when no file has been selected.
                          Type
                          | ReactElement
                          | ((
                          props: object,
                          ) => ReactElement)
                          Description
                          Allows you to replace the component's HTML element with a different tag or component. Learn more

                          <FileInput.HiddenInput>

                          PropType
                          Allows you to replace the component's HTML element with a different tag or component. Learn more
                          | ReactElement
                          | ((
                          props: object,
                          ) => ReactElement)
                          Type
                          | ReactElement
                          | ((
                          props: object,
                          ) => ReactElement)
                          Description
                          Allows you to replace the component's HTML element with a different tag or component. Learn more

                          <FileInput.ErrorText>

                          PropType
                          Optional error indicator icon.
                          | LucideIcon
                          | ReactNode
                          Allows you to replace the component's HTML element with a different tag or component. Learn more
                          | ReactElement
                          | ((
                          props: object,
                          ) => ReactElement)
                          Type
                          | LucideIcon
                          | ReactNode
                          Description
                          Optional error indicator icon.
                          Type
                          | ReactElement
                          | ((
                          props: object,
                          ) => ReactElement)
                          Description
                          Allows you to replace the component's HTML element with a different tag or component. Learn more
                          Last updated on by Ryan Bower