Skip to main content

File input

Let people attach one or more files with a file input. See examples for accepted file types and multiple uploads.

Examples

Default

Breakpoints

Mobile

320px

Mobile Lg

480px

Tablet

640px

Desktop

1024px
No file selected.
file-input-demo.tsx
import { FileInput } from '@uswds-tailwind/react'
export default function FileInputDemo() {
return (
<FileInput.Root>
<FileInput.Label>Input accepts a single file</FileInput.Label>
<FileInput.SrStatus />
<FileInput.Dropzone>
<FileInput.ItemGroup>
{({ acceptedFiles }) => (
<>
<FileInput.PreviewHeader>
<FileInput.PreviewTitle />
<FileInput.ChangeTrigger />
</FileInput.PreviewHeader>
{acceptedFiles.map(file => (
<FileInput.Item key={file.name} file={file}>
<FileInput.ItemPreview>
{file.type.startsWith('image/')
? <FileInput.ItemPreviewImage />
: <FileInput.ItemPreviewIcon />}
<FileInput.ItemName />
</FileInput.ItemPreview>
</FileInput.Item>
))}
</>
)}
</FileInput.ItemGroup>
<FileInput.Instructions />
<FileInput.ErrorMessage>This is not a valid file type.</FileInput.ErrorMessage>
<FileInput.Input />
</FileInput.Dropzone>
</FileInput.Root>
)
}

Specific File Types

Breakpoints

Mobile

320px

Mobile Lg

480px

Tablet

640px

Desktop

1024px
Select PDF or TXT files
No file selected.
file-input-specific-types-demo.tsx
import { FileInput } from '@uswds-tailwind/react'
export default function FileInputSpecificTypesDemo() {
return (
<FileInput.Root accept=".pdf,.txt">
<FileInput.Label>Input accepts only specific file types</FileInput.Label>
<div id="file-input-types-hint" className="text-gray-50">Select PDF or TXT files</div>
<FileInput.SrStatus />
<FileInput.Dropzone>
<FileInput.ItemGroup>
{({ acceptedFiles }) => (
<>
<FileInput.PreviewHeader>
<FileInput.PreviewTitle />
<FileInput.ChangeTrigger />
</FileInput.PreviewHeader>
{acceptedFiles.map(file => (
<FileInput.Item key={file.name} file={file}>
<FileInput.ItemPreview>
{file.type.startsWith('image/')
? <FileInput.ItemPreviewImage />
: <FileInput.ItemPreviewIcon />}
<FileInput.ItemName />
</FileInput.ItemPreview>
</FileInput.Item>
))}
</>
)}
</FileInput.ItemGroup>
<FileInput.Instructions />
<FileInput.ErrorMessage>This is not a valid file type.</FileInput.ErrorMessage>
<FileInput.Input aria-describedby="file-input-types-hint" />
</FileInput.Dropzone>
</FileInput.Root>
)
}

Accept Multiple Files

Breakpoints

Mobile

320px

Mobile Lg

480px

Tablet

640px

Desktop

1024px
No files selected.
file-input-multiple-demo.tsx
import { FileInput } from '@uswds-tailwind/react'
export default function FileInputMultipleDemo() {
return (
<FileInput.Root multiple>
<FileInput.Label>Input accepts multiple files</FileInput.Label>
<FileInput.SrStatus />
<FileInput.Dropzone>
<FileInput.ItemGroup>
{({ acceptedFiles }) => (
<>
<FileInput.PreviewHeader>
<FileInput.PreviewTitle />
<FileInput.ChangeTrigger />
</FileInput.PreviewHeader>
{acceptedFiles.map(file => (
<FileInput.Item key={file.name} file={file}>
<FileInput.ItemPreview>
{file.type.startsWith('image/')
? <FileInput.ItemPreviewImage />
: <FileInput.ItemPreviewIcon />}
<FileInput.ItemName />
</FileInput.ItemPreview>
</FileInput.Item>
))}
</>
)}
</FileInput.ItemGroup>
<FileInput.Instructions />
<FileInput.ErrorMessage>This is not a valid file type.</FileInput.ErrorMessage>
<FileInput.Input />
</FileInput.Dropzone>
</FileInput.Root>
)
}

Component API

Root connects the file control, dropzone, instructions, error, and preview parts.

Root<div>

Owns accepted files and rejects the entire selection if any file fails accept validation.

PropTypeDefaultDescription
acceptstring—Accepted file types.
multiplebooleanfalseAllows more than one file.
disabledbooleanfalseDisables selection.
errorTextstring"Error: This is not a valid file type."Message for rejected files. Defaults to "Error: This is not a valid file type."
ariaDisabledbooleanfalseMarks the input disabled for assistive technology while keeping it operable.
ids{ root?: string; label?: string; dropzone?: string; box?: string; input?: string; instructions?: string; itemGroup?: string; previewHeading?: string; srStatus?: string; errorText?: string }—Overrides generated part IDs. Use Root IDs when a label or external control needs a stable input or trigger target.
AttributeValuePurpose
data-disabledPresent when disabledStyle the disabled state.

Label<label>

Names the file input.

AttributeValuePurpose
data-disabledPresent when disabledStyle the disabled state.

SrStatus<div>

Announces file selection status after a one-second delay. Initially disabled inputs hide this region.

Dropzone<div>

Displays the drag and drop target.

AttributeValuePurpose
data-invalidPresent when invalidStyle the error state.
data-draggingPresent while dragging filesStyles drag feedback.

Input<input>

Native file input over the dropzone. Pass native name, required, and onChange props here.

Instructions<div>

Explains how to choose files; children replace the default text.

ErrorMessage<div>

Displays rejected-file feedback.

ItemGroup<div>

Contains previews of accepted files.

PropTypeDescription
childrenReactNode | ({ acceptedFiles: File[] }) => ReactNodeCan render from accepted files.
AttributeValuePurpose
data-validPresent when files are selectedStyle the populated preview.

PreviewHeader<div>

Groups the preview heading and change action.

PreviewTitle<div>

Displays the selected-file heading.

Item<div>

Provides one file to the preview parts.

PropTypeDescription
fileFile (required)The file represented by this item.

ItemPreview<div>

Arranges the preview icon, image, and file name.

ItemPreviewIcon<div>

Displays a file-type icon.

AttributeValuePurpose
data-typepdf | word | excel | video | generic | imageStyles the file icon.

ItemPreviewImage<img>

Displays an image thumbnail when available.

ItemName<div>

Displays the file name by default.

ChangeTrigger<span>

Displays decorative change-files text. The overlaid native Input opens the file picker.