EXEPERTAI LAB

Research alpha

Time Machine
EXEPERTAI LAB
GALLERY / COLLECTION
← Browse Astryx gallery
FileInput·component·@astryxdesign/core

File Input

FileInput provides file upload with optional drag-and-drop support. Use it for single or multiple file selection with built-in validation for file type, size, and count. Pair with validation status for upload feedback.

Open in Playground @astryxdesign/core/FileInput

Showcases and examples

2 documented examples

File Input

FileInput API entry

Preview loads on approachPreview loads on approach
Exact source · file-input-showcase
// Copyright (c) Meta Platforms, Inc. and affiliates.

'use client';

import {useState} from 'react';
import {FileInput} from '@astryxdesign/core/FileInput';

export default function FileInputShowcase() {
  const [value, setValue] = useState<File | File[] | null>(null);
  return (
    <div style={{width: 350}}>
      <FileInput
        label="Upload file"
        value={value}
        onChange={setValue}
        placeholder="Drag files here or click to browse"
      />
    </div>
  );
}

Usage

FileInput provides file upload with optional drag-and-drop support. Use it for single or multiple file selection with built-in validation for file type, size, and count. Pair with validation status for upload feedback.

  • Always specify an accept prop to guide users toward valid file types.
  • Use maxSize and maxFiles to prevent oversized uploads; the component handles validation and error display automatically.
  • Add a description to communicate constraints like file size limits or accepted formats.
  • Use changeAction for immediate upload workflows that benefit from optimistic UI.
  • Don't use FileInput for directory or folder uploads; that is not supported in v1.
  • Don't avoid dropzone mode unless space is constrained; drag-and-drop is the expected interaction for file uploads.
  • Don't wrap a disabled FileInput in Tooltip to explain why it's disabled; disabled controls swallow the hover events the wrapper needs. Use the disabledMessage prop instead.

Typed props

PropType and behavior
labelstring · required
Accessible label for the file input.
valueFile | File[] | null · required
Currently selected file(s). Controlled component.
onChange(files: File | File[] | null) => void · required
Callback fired when files are selected or removed.
changeAction(files: File | File[] | null) => Promise<void>
Async change action (React 19 transitions pattern). Use for immediate upload on file selection.
acceptstring
Accepted file types. Uses the HTML accept attribute format (e.g. "image/*", ".pdf,.doc").
isMultipleboolean · default false
Whether multiple files can be selected. When true, value and onChange use File[] instead of File.
maxSizenumber
Maximum file size in bytes. Files exceeding this are rejected with an error status.
maxFilesnumber
Maximum number of files (only applies when isMultiple is true).
isLabelHiddenboolean · default false
Visually hides the label while keeping it accessible to screen readers.
descriptionstring
Description text displayed between the label and input.
isOptionalboolean · default false
Displays an "Optional" indicator next to the label. Mutually exclusive with isRequired.
isRequiredboolean · default false
Displays a "Required" indicator next to the label and adds a screen-reader-only "Required" description to the trigger (assistive tech does not reliably announce aria-required on the trigger). Mutually exclusive with isOptional.
isDisabledboolean · default false
Disables the input, preventing interaction and dimming the element.
disabledMessagestring
Explains why the input is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the trigger focusable via aria-disabled (opening the file picker stays blocked). Use this instead of wrapping a disabled FileInput in Tooltip; disabled controls swallow the hover events an external Tooltip needs.
isLoadingboolean · default false
Puts the input in a loading state, showing a spinner and setting aria-busy.
placeholderstring · default "Choose file" or "Choose files"
Placeholder text shown when no file is selected.
mode'input' | 'dropzone' · default 'input'
Visual mode. 'input' is a compact inline style; 'dropzone' is a larger area with drag-and-drop support.
status{type: 'error' | 'warning' | 'success', message?: string}
Validation status: applies a colored border. If message is provided, displays a floating message below the input. Error type also sets aria-invalid.
statusVariant'attached' | 'detached' | 'tooltip' · default 'attached'
How the status message is placed relative to the input. attached overlaps directly below the input (bordered treatment); detached floats below as a separate element with spacing; tooltip hides the message box and surfaces it in a tooltip on the status icon.
labelTooltipstring
Tooltip text displayed in an info icon at the end of the label.
widthSizeValue
Width of the field (number = pixels, string used as-is, e.g. "100%"). Sizes the whole field (label, control, and status) so they stay aligned.

Anatomy

Label · required

Text that identifies the field. Always rendered for accessibility even when visually hidden.

Description · optional

Helper text between the label and the drop zone explaining accepted formats or size limits.

Drop zone · required

The clickable area for file selection. In dropzone mode, also accepts dragged files.

Upload icon · optional

An arrow icon in the drop zone hinting at the upload action.

Placeholder · optional

Hint text shown when no files are selected.

File name display · optional

Shows the name(s) of selected files.

Clear button · optional

A close button that removes selected files and returns focus to the input.

Spinner · optional

Loading indicator that appears during async upload actions.

Status message · optional

Validation feedback showing error, warning, or success with a message.

Theming

Targets

astryx-file-input

Visual props: mode, status

astryx-file-input-icon

Visual props: mode