FileTrigger

A FileTrigger allows a user to access the file system with any pressable React Aria or React Spectrum component, or custom components built with usePress.

installyarn add @adobe/react-spectrum
added3.35.0
usageimport {FileTrigger} from '@adobe/react-spectrum'

Example#


import {FileTrigger, Button} from '@adobe/react-spectrum';

function Example(){
  let [file, setFile] = React.useState(null);

  return (
    <>
      <FileTrigger
        onSelect={(e) => {
          let files = Array.from(e);
          let filenames = files.map((file) => file.name);
          setFile(filenames);
        }}>
        <Button variant="accent">Select a file</Button>
      </FileTrigger>
      {file && file}
    </>
  )
}
import {FileTrigger, Button} from '@adobe/react-spectrum';

function Example(){
  let [file, setFile] = React.useState(null);

  return (
    <>
      <FileTrigger
        onSelect={(e) => {
          let files = Array.from(e);
          let filenames = files.map((file) => file.name);
          setFile(filenames);
        }}>
        <Button variant="accent">Select a file</Button>
      </FileTrigger>
      {file && file}
    </>
  )
}
import {
  Button,
  FileTrigger
} from '@adobe/react-spectrum';

function Example() {
  let [file, setFile] =
    React.useState(null);

  return (
    <>
      <FileTrigger
        onSelect={(
          e
        ) => {
          let files =
            Array.from(
              e
            );
          let filenames =
            files.map((
              file
            ) =>
              file.name
            );
          setFile(
            filenames
          );
        }}
      >
        <Button variant="accent">
          Select a file
        </Button>
      </FileTrigger>
      {file && file}
    </>
  );
}

Content#


A FileTrigger wraps around a pressable child such as a button, and includes a visually hidden input element that allows the user to select files from their device.

import {FileTrigger, Button} from '@adobe/react-spectrum';

<FileTrigger>
  <Button />
</FileTrigger>
import {FileTrigger, Button} from '@adobe/react-spectrum';

<FileTrigger>
  <Button />
</FileTrigger>
import {
  Button,
  FileTrigger
} from '@adobe/react-spectrum';

<FileTrigger>
  <Button />
</FileTrigger>

If a visual label is not provided on the pressable child, then an aria-label or aria-labelledby prop must be passed to identify the file trigger to assistive technology.

Accepted file types#


By default, the file trigger will accept any file type. To support only certain file types, pass an array of the mime type of files via the acceptedFileTypes prop.

<FileTrigger acceptedFileTypes={['image/png']}>
  <Button variant="primary">Select files</Button>
</FileTrigger>
<FileTrigger acceptedFileTypes={['image/png']}>
  <Button variant="primary">Select files</Button>
</FileTrigger>
<FileTrigger
  acceptedFileTypes={[
    'image/png'
  ]}
>
  <Button variant="primary">
    Select files
  </Button>
</FileTrigger>

Multiple files#


A file trigger can accept multiple files by passsing the allowsMultiple property.

<FileTrigger allowsMultiple>
  <Button variant="primary">Upload your files</Button>
</FileTrigger>
<FileTrigger allowsMultiple>
  <Button variant="primary">Upload your files</Button>
</FileTrigger>
<FileTrigger
  allowsMultiple
>
  <Button variant="primary">
    Upload your files
  </Button>
</FileTrigger>

Directory selection#


To enable selecting directories instead of files, use the acceptDirectory property.

This reflects the webkitdirectory HTML attribute and allows users to select directories and their contents. Please note that support for this feature varies from browser to browser.

function Example() {
  let [files, setFiles] = React.useState([]);

  return (
    <>
      <FileTrigger
        acceptDirectory
        onSelect={(e) => {
          if (e) {
            let fileList = [...e].map((file) =>
              file.webkitRelativePath !== ''
                ? file.webkitRelativePath
                : file.name
            );
            setFiles(fileList);
          }
        }}
      >
        <Button variant="accent">Upload</Button>
      </FileTrigger>
      {files && (
        <ul>
          {files.map((file, index) => <li key={index}>{file}</li>)}
        </ul>
      )}
    </>
  );
}
function Example() {
  let [files, setFiles] = React.useState([]);

  return (
    <>
      <FileTrigger
        acceptDirectory
        onSelect={(e) => {
          if (e) {
            let fileList = [...e].map((file) =>
              file.webkitRelativePath !== ''
                ? file.webkitRelativePath
                : file.name
            );
            setFiles(fileList);
          }
        }}
      >
        <Button variant="accent">Upload</Button>
      </FileTrigger>
      {files && (
        <ul>
          {files.map((file, index) => (
            <li key={index}>{file}</li>
          ))}
        </ul>
      )}
    </>
  );
}
function Example() {
  let [files, setFiles] =
    React.useState([]);

  return (
    <>
      <FileTrigger
        acceptDirectory
        onSelect={(
          e
        ) => {
          if (e) {
            let fileList =
              [...e].map(
                (file) =>
                  file
                      .webkitRelativePath !==
                      ''
                    ? file
                      .webkitRelativePath
                    : file
                      .name
              );
            setFiles(
              fileList
            );
          }
        }}
      >
        <Button variant="accent">
          Upload
        </Button>
      </FileTrigger>
      {files && (
        <ul>
          {files.map((
            file,
            index
          ) => (
            <li
              key={index}
            >
              {file}
            </li>
          ))}
        </ul>
      )}
    </>
  );
}

Media capture#


To specify the media capture mechanism to capture media on the spot, pass user for the user-facing camera or environment for the outward-facing camera via the defaultCamera prop.

This behavior only works on mobile devices. On desktop devices, it will open the file system like normal. Read more about capture.

<FileTrigger defaultCamera="environment">
  <Button variant="accent">Open Camera</Button>
</FileTrigger>
<FileTrigger defaultCamera="environment">
  <Button variant="accent">Open Camera</Button>
</FileTrigger>
<FileTrigger defaultCamera="environment">
  <Button variant="accent">
    Open Camera
  </Button>
</FileTrigger>

Props#


NameTypeDescription
acceptedFileTypesArray<string>Specifies what mime type of files are allowed.
allowsMultiplebooleanWhether multiple files can be selected.
defaultCamera'user''environment'Specifies the use of a media capture mechanism to capture the media on the spot.
childrenReactNodeThe children of the component.
acceptDirectorybooleanEnables the selection of directories instead of individual files.
Events
NameTypeDescription
onSelect( (files: FileListnull )) => voidHandler when a user selects a file.