FileInput

Capture files from user

PackageIcon

Usage

FileInput component supports Input and Input.Wrapper component features and all input element props. The FileInput documentation does not include all features supported by the component – see the Input documentation to learn about all available features.

Input description

Variant
Size
Radius
import { FileInput } from '@mantine/core';

function Demo() {
  return (
    <FileInput
      label="Input label"
      description="Input description"
      placeholder="Input placeholder"
    />
  );
}

Loading state

Set loading prop to display a loading indicator. By default, the loader is displayed on the right side of the input. You can change the position with the loadingPosition prop to 'left' or 'right'. This is useful for async operations like API calls, searches, or validations:

import { FileInput } from '@mantine/core';

function Demo() {
  return <FileInput placeholder="Upload file" loading />;
}

Controlled

When multiple is false:

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

function Demo() {
  const [value, setValue] = useState<File | null>(null);
  return <FileInput value={value} onChange={setValue} />;
}

When multiple is true:

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

function Demo() {
  const [value, setValue] = useState<File[]>([]);
  return <FileInput multiple value={value} onChange={setValue} />;
}

Uncontrolled

FileInput can be used with uncontrolled forms the same way as a native input[type="file"]. Set the name attribute to include file input value in FormData object on form submission. To control the initial value in uncontrolled forms, use the defaultValue prop.

Example usage of uncontrolled FileInput with FormData:

import { FileInput } from '@mantine/core';

function Demo() {
  return (
    <form
      onSubmit={(event) => {
        event.preventDefault();
        const formData = new FormData(event.currentTarget);
        const files = formData.getAll('file');
        console.log('File input value:', files);
      }}
    >
      <FileInput label="Upload your file" name="file" />
      <button type="submit">Submit</button>
    </form>
  );
}

Multiple

Set multiple to allow the user to pick more than one file:

import { FileInput } from '@mantine/core';

function Demo() {
  return <FileInput label="Upload files" placeholder="Upload files" multiple />;
}

Accept

Set the accept prop to restrict file selection to specific mime types:

import { FileInput } from '@mantine/core';

function Demo() {
  return (
    <FileInput accept="image/png,image/jpeg" label="Upload files" placeholder="Upload files" />
  );
}

Clearable

Set the clearable prop to display a clear button in the right section of the input when a file is selected. Note that if you define a custom right section, the clear button will not be rendered.

import { FileInput } from '@mantine/core';

function Demo() {
  return <FileInput clearable label="Upload files" placeholder="Upload files" />;
}

Clear section mode

The clearSectionMode prop determines how the clear button and rightSection are rendered:

  • 'both' (default) – render both the clear button and rightSection
  • 'rightSection' – render only the user-supplied rightSection, ignore clear button
  • 'clear' – render only the clear button, ignore rightSection
import { CaretDownIcon } from '@phosphor-icons/react';
import { FileInput, Stack } from '@mantine/core';

function Demo() {
  return (
    <Stack>
      <FileInput
        label="clearSectionMode='both' (default)"
        placeholder="Pick file"
        clearable
        rightSection={<CaretDownIcon size={16} />}
        clearSectionMode="both"
      />

      <FileInput
        label="clearSectionMode='rightSection'"
        placeholder="Pick file"
        clearable
        rightSection={<CaretDownIcon size={16} />}
        clearSectionMode="rightSection"
      />

      <FileInput
        label="clearSectionMode='clear'"
        placeholder="Pick file"
        clearable
        rightSection={<CaretDownIcon size={16} />}
        clearSectionMode="clear"
      />
    </Stack>
  );
}

Custom value component

import { FileInput, FileInputProps, Pill } from '@mantine/core';

const ValueComponent: FileInputProps['valueComponent'] = ({ value }) => {
  if (value === null) {
    return null;
  }

  if (Array.isArray(value)) {
    return (
      <Pill.Group>
        {value.map((file, index) => (
          <Pill key={index}>{file.name}</Pill>
        ))}
      </Pill.Group>
    );
  }

  return <Pill>{value.name}</Pill>;
};

function Demo() {
  return (
    <FileInput
      label="Upload files"
      placeholder="Upload files"
      multiple
      valueComponent={ValueComponent}
    />
  );
}

Error state

Invalid name

import { FileInput } from '@mantine/core';

function Demo() {
  return (
    <>
      <FileInput label="Boolean error" placeholder="Boolean error" error />
      <FileInput
        mt="md"
        label="With error message"
        placeholder="With error message"
        error="Invalid name"
      />
    </>
  );
}

Disabled state

import { FileInput } from '@mantine/core';

function Demo() {
  return <FileInput disabled label="Disabled input" placeholder="Disabled input" />;
}

Left and right sections

FileInput supports leftSection and rightSection props. These sections are rendered with absolute positioning inside the input wrapper. You can use them to display icons, input controls, or any other elements.

You can use the following props to control sections styles and content:

  • rightSection / leftSection – React node to render on the corresponding side of input
  • rightSectionWidth/leftSectionWidth – controls the width of the right section and padding on the corresponding side of the input. By default, it is controlled by the component size prop.
  • rightSectionPointerEvents/leftSectionPointerEvents – controls the pointer-events property of the section. If you want to render a non-interactive element, set it to none to pass clicks through to the input.
import { FileInput } from '@mantine/core';
import { FileTextIcon } from '@phosphor-icons/react';

function Demo() {
  const icon = <FileTextIcon size={18} />;

  return (
    <>
      <FileInput
        leftSection={icon}
        label="Attach your CV"
        placeholder="Your CV"
        leftSectionPointerEvents="none"
      />
      <FileInput
        rightSection={icon}
        label="Attach your CV"
        placeholder="Your CV"
        rightSectionPointerEvents="none"
        mt="md"
      />
    </>
  );
}

Styles API

FileInput supports the Styles API; you can add styles to any inner element of the component with the classNames prop. Follow the Styles API documentation to learn more.

Description

Error

Component Styles API

Hover over selectors to highlight corresponding elements

/*
 * Hover over selectors to apply outline styles
 *
 */

Get element ref

import { useRef } from 'react';
import { FileInput } from '@mantine/core';

function Demo() {
  const ref = useRef<HTMLButtonElement>(null);
  return <FileInput ref={ref} />;
}

Accessibility

If FileInput is used without the label prop, it will not be announced properly by screen readers:

import { FileInput } from '@mantine/core';

// Inaccessible input – screen reader will not announce it properly
function Demo() {
  return <FileInput />;
}

Set aria-label to make the input accessible. In this case the label will not be visible, but screen readers will announce it:

import { FileInput } from '@mantine/core';

// Accessible input – it has aria-label
function Demo() {
  return <FileInput aria-label="My input" />;
}

If the label prop is set, the input will be accessible and it is not required to set aria-label:

import { FileInput } from '@mantine/core';

// Accessible input – it has associated label element
function Demo() {
  return <FileInput label="My input" />;
}

FileInputProps type

FileInputProps type is a generic interface which accepts a single type argument: the multiple value.

import type { FileInputProps } from '@mantine/core';

type SingleInputProps = FileInputProps<false>;
type MultipleInputProps = FileInputProps<true>;