Skip to content

File Input

A file-upload control for selecting supporting documents by browsing or dragging files into a bounded upload area.

Component

Use fd-file-input when a task genuinely requires supporting files and the user benefits from clear restrictions, visible upload states, and predictable follow-up actions.

When to use

  • Required supporting documents — identity verification, supporting evidence, or correspondence attachments.
  • Short batches of files — when users may attach one or a few files and benefit from drag-and-drop as an optional shortcut.
  • Upload workflows that need visible file state — such as uploading, uploaded, failed, or invalid rows managed by the host application.

When not to use

  • Optional documents — avoid asking for uploads unless the service genuinely needs them.
  • Large or advanced transfer workflows — resumable uploads, background sync, directory upload, or preview-heavy media workflows need a dedicated uploader pattern.
  • Many separate document requirements — if each document has a distinct meaning, use a dedicated upload step or one input per requirement instead of a generic multi-file bucket.

Examples

File input states — empty, drag target, files attached, mixed row states, and limit reached. Open Storybook for interactive controls. View in Storybook →

Properties

NameTypeDefaultDescription
namestring``Form field name used when accepted files are submitted.
labelstring``Visible field label rendered inside the container.
hintstring``Persistent plain-language guidance for accepted file types, counts, or sizes.
buttonTextstringDEFAULT_SELECT_LABELText shown on the browse affordance over the native file input.
dropTextstringDEFAULT_DROP_TEXTSupporting drag-and-drop instruction shown next to the browse affordance.
errorMessagestring``Authored field-level error copy shown when the component reveals invalid state.
limitTextstringDEFAULT_LIMIT_MESSAGEInformational message shown when maxFiles has been reached.
requiredbooleanfalseRequires at least one accepted file before the field is valid.
disabledbooleanfalseDisables browse, drop, and row actions.
multiplebooleanfalseAllows multiple accepted files and repeated selection up to maxFiles.
acceptstring``Native accept filter used for browse selection and mirrored during drop validation.
maxFilesnumber | undefinedundefinedMaximum number of accepted files allowed at one time.
maxFileSizenumber | undefinedundefinedMaximum file size in bytes for any accepted file.
itemsFileInputItem[][]Property-only row model for authored upload states such as uploading, success, error, and invalid.
  • items is a property-only API. Set it from JavaScript rather than authoring it as an HTML attribute.
  • Accepted files remain the source of truth for form submission, required, and maxFiles behavior even when items is provided.

Events

NameDetailDescription
fd-file-input-change{ files: File[]; rejectedFiles: FileInputRejectedFile[] }Fired after browse or drop selection is processed. Includes accepted files and local validation rejections.
fd-file-input-action{ action: "cancel" | "remove" | "retry" | "dismiss"; itemId: string }Fired when the user activates a per-file row action.

CSS custom properties

NameDefaultDescription
--fd-file-input-gapvar(--fdic-spacing-md, 16px)Vertical gap between the main content blocks inside the container.
--fd-file-input-radiusvar(--fdic-corner-radius-md, 5px)Outer container corner radius.
--fd-file-input-border-colorvar(--fdic-color-border-input, #bdbdbf)Container border color at rest.
--fd-file-input-border-color-hovervar(--fdic-color-border-input-active, #424244)Container border color for hover and drag-target emphasis.
--fd-file-input-backgroundvar(--fdic-color-bg-base, #ffffff)Container background color.
--fd-file-input-focus-ringvar(--fdic-color-border-input-focus, #38b6ff)Outer focus glow color when the internal input is focused.
--fd-file-input-drop-overlayvar(--fdic-color-overlay-hover, rgba(0, 0, 0, 0.04))Overlay color used for the active drop-target state.
--fd-file-input-item-border-colorvar(--fdic-color-border-input-interactive, #e8e8ed)Border color for file rows.
--fd-file-input-progress-colorvar(--fdic-color-border-input-focus, #38b6ff)Indicator color for uploading rows.

Shadow parts

NameDescription
containerOuter upload container.
labelVisible field label.
browse-buttonVisual chrome for the browse affordance that overlays the native file input.
nativeInternal native <input type="file">.
drop-textVisible drag-and-drop instruction text.
hintPersistent guidance text.
errorField-level error message.
limitLimit-reached informational message.
summaryFallback selected-file summary when no authored rows are provided.
listList wrapper for authored file rows.
itemIndividual file row.
item-statusPer-file status text and icon wrapper.
item-actionPer-file action button.
live-regionScreen-reader-only announcement region for drop and selection status.

Best practices

Do

Explain file restrictions in plain language

Tell users which file types are accepted, how many files they may attach, and the size limit before they choose a file.

Don't

Rely on accept alone

File-picker filtering is not enough guidance. Keep restrictions visible in the UI.

Do

Keep upload state visible

Show users which files are uploading, succeeded, failed, or invalid so they know what needs attention.

Don't

Hide failure behind a generic error

Use clear status text like “Upload failed” or “Invalid file type” instead of vague warnings.

Do

Prefer one file per input unless batching is expected

Small, explicit upload requirements are easier for users to understand and recover from.

Don't

Treat drag-and-drop as required

Drag-and-drop is optional enhancement. The browse path must remain the primary reliable path.

Content guidelines

  • State the need clearly. If the document is sensitive or high-stakes, explain why the service needs it.
  • Use explicit action labels. “Select file” is clearer before a file is chosen than “Upload”.
  • Keep limit text calm and specific. For example: “All set! You’ve reached the file upload limit.”
  • Avoid implying storage success too early. Only show “Upload successful” after the host workflow has actually accepted the file.
  • Prefer one file per input unless users routinely attach a small set of related files. This matches USWDS guidance and reduces confusion around multi-select gestures.

Accessibility

  • fd-file-input keeps a real internal <input type="file"> as the semantic foundation.
  • Progressive enhancement: browsing remains available even if drag-and-drop is unsupported or ignored.
  • Labeling: the component owns its visible label and hint text internally.
  • Description wiring: the internal file input owns aria-describedby for hint text, visible field-level error text, and live-region announcements.
  • Invalid state: the host uses data-user-invalid for visible invalid styling, while the internal input gets aria-invalid="true" only when that visible invalid state is active.
  • Keyboard: users can tab to the browse control and any row actions. Drag-and-drop is never required for keyboard completion.
  • Color independence: every file row includes visible status text in addition to status color and indicator lines.
  • Forced colors and reduced motion: the component preserves borders, focus treatment, and readable state cues in those modes.

Known limitations

  • fd-file-input does not own network upload transport. The host application is responsible for actual upload lifecycle, retry behavior, and persistence.
  • The items row model is a property-only API. Set it from JavaScript rather than markup.
  • When you provide items, keep them aligned with the accepted files that should remain visible to the user.
  • v1 does not support previews, directory upload, paste-to-upload, chunked uploads, or drag-only workflows.
  • Form Field — wrapper-based shell for shared label, description, and error authorship across control families
  • Input — single-line text entry and field-level validation patterns
  • Field — supporting composition helper for fd-label, fd-input, and fd-message
  • Message — standalone supporting primitive for validation and helper messaging