FileButton

Open file picker with a button click

Import

Usage

import { useState } from 'react';
import { FileButton, Button, Group, Text } from '@mantine/core';

function Demo() {
  const [file, setFile] = useState<File | null>(null);
  return (
    <>
      <Group justify="center">
        <FileButton onChange={setFile} accept="image/png,image/jpeg">
          {(props) => <Button {...props}>Upload image</Button>}
        </FileButton>
      </Group>

      {file && (
        <Text size="sm" ta="center" mt="sm">
          Picked file: {file.name}
        </Text>
      )}
    </>
  );
}

Multiple files

Set multiple prop to allow picking multiple files:

    import { useState } from 'react';
    import { FileButton, Button, Group, Text } from '@mantine/core';
    
    function Demo() {
      const [files, setFiles] = useState<File[]>([]);
      return (
        <>
          <Group justify="center">
            <FileButton onChange={setFiles} accept="image/png,image/jpeg" multiple>
              {(props) => <Button {...props}>Upload image</Button>}
            </FileButton>
          </Group>
    
          {files.length > 0 && (
            <Text size="sm" mt="sm">
              Picked files:
            </Text>
          )}
    
          <ul>
            {files.map((file, index) => (
              <li key={index}>{file.name}</li>
            ))}
          </ul>
        </>
      );
    }

    Reset file

    resetRef should be used to fix issue with stale value on hidden input element as input type file cannot be controlled. Call resetRef when user selection is cleared:

    import { useState, useRef } from 'react';
    import { FileButton, Button, Group, Text } from '@mantine/core';
    
    function Demo() {
      const [file, setFile] = useState<File | null>(null);
      const resetRef = useRef<() => void>(null);
    
      const clearFile = () => {
        setFile(null);
        resetRef.current?.();
      };
    
      return (
        <>
          <Group justify="center">
            <FileButton resetRef={resetRef} onChange={setFile} accept="image/png,image/jpeg">
              {(props) => <Button {...props}>Upload image</Button>}
            </FileButton>
            <Button disabled={!file} color="red" onClick={clearFile}>
              Reset
            </Button>
          </Group>
    
          {file && (
            <Text size="sm" ta="center" mt="sm">
              Picked file: {file.name}
            </Text>
          )}
        </>
      );
    }

    Incompatible with server components

    FileButton is not compatible with React server components as it requires function as children. To use FileButton add "use client;" at the top of the file.