Gecko UIGecko UI

RHFFileInput

FileInput wired to React Hook Form

RHFFileInput

FileInput wired to React Hook Form.

Installation

import { RHFFileInput } from '@geckoui/geckoui';

Basic Usage

nothing picked

import { FormProvider, useForm } from 'react-hook-form';
import { RHFFileInput, type PickedFile } from '@geckoui/geckoui';

function ApplicationForm() {
  const methods = useForm<{ cv: PickedFile | null }>({ defaultValues: { cv: null } });

  return (
    <FormProvider {...methods}>
      <form onSubmit={methods.handleSubmit(save)}>
        <RHFFileInput name="cv" accept=".pdf,.docx" />
      </form>
    </FormProvider>
  );
}

The field holds a PickedFile when single and a PickedFile[] when multiple. Files are real File objects, so they go straight into a FormData.

Props API

PropTypeDefaultDescription
namestringrequiredThe field path
controlControl-Taken from FormProvider when left out
rulesRegisterOptions-Validation rules
onChange(value) => void-Called alongside the form update
...restFileInputProps-Everything FileInput takes, except value and aria-invalid

aria-invalid is set for you from the field's own error, so it is not yours to pass.

Requiring one

<RHFFileInput name="avatar" accept="image/*" rules={{ required: 'Pick a file' }} />
<RHFError name="avatar" />

A single field holds null until something is picked, so required catches it.

Several files

nothing picked

<RHFFileInput
  name="docs"
  multiple
  append
  unique
  max={3}
  rules={{ validate: (files) => files.length > 0 || 'Add at least one' }}
/>
<RHFError name="docs" />

A multiple field holds [] rather than null, and required does not catch an empty array — use validate, as above.

append, unique and max are only accepted alongside multiple; TypeScript rejects them otherwise.

Uploading

const onSubmit = async ({ docs }: { docs: PickedFile[] }) => {
  const body = new FormData();

  docs.forEach((file) => body.append('files', file, file.path || file.name));

  await fetch('/upload', { method: 'POST', body });
};

path carries the folder a dropped file came from, so a directory upload can be rebuilt on the server. It is "" for a file picked on its own.