FileButton

Open file picker with a button click

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 the 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 the issue with stale value on the hidden input element as input type file cannot be controlled. Call resetRef when the 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 because it requires using function as children. To use FileButton, add "use client;" at the top of the file.