EdgeStore

File Field

A compact single-file input that sits in a form next to regular fields.

Drop a file or browsePDF, DOC or DOCX · 5 MB

Once a file is chosen, the field shows it with its progress and a remove button instead of the drop area.

Installation

Use the shadcn CLI to add the component to your project.

npx shadcn@latest add https://edgestore.dev/r/file-field.json

Usage

Install or copy the component from Installation before using this example.

'use client';

import { FileField } from '@/components/upload/file-field';
import { DOCUMENT_ACCEPT } from '@/components/upload/upload-utils';
import {
  UploaderProvider,
  type UploadFn,
} from '@/components/upload/uploader-provider';
import { useEdgeStore } from '@/lib/edgestore';
import * as React from 'react';

export function FileFieldUsage() {
  const { edgestore } = useEdgeStore();

  const uploadFn: UploadFn = React.useCallback(
    async ({ file, onProgressChange, signal }) => {
      const res = await edgestore.publicFiles.upload({
        file,
        signal,
        onProgressChange,
      });
      // you can run some server action or api here
      // to add the necessary data to your database
      console.log(res);
      return res;
    },
    [edgestore],
  );

  return (
    <UploaderProvider uploadFn={uploadFn} autoUpload>
      <label id="resume-label" htmlFor="resume-input">
        Resume
      </label>
      <FileField
        inputId="resume-input"
        aria-labelledby="resume-label"
        accept={DOCUMENT_ACCEPT}
        typesLabel="PDF, DOC or DOCX"
        maxSize={1024 * 1024 * 5} // 5 MB
      />
    </UploaderProvider>
  );
}

Props

PropTypeDefaultDescription
inputIdstringId for the hidden file input, so a <label htmlFor> opens the file dialog.
maxSizenumberMaximum file size in bytes.
acceptAcceptall typesAccepted file types, in react-dropzone's format.
typesLabelstringHuman-readable list of accepted types, shown in the hint and in error messages.
disabledbooleanfalseDisables the component.
aria-labelledbystringId of the element that labels the field.

With React Hook Form

Give each field its own UploaderProvider and write the completed file into the form value from onChange:

const handleChange = React.useCallback(
  ({ completedFiles }: { completedFiles: CompletedFileState[] }) => {
    const [completed] = completedFiles;
    field.onChange(
      completed ? { filename: completed.file.name, url: completed.url } : null,
    );
  },
  [field],
);

<UploaderProvider uploadFn={uploadFn} onChange={handleChange} autoUpload>
  <FileField aria-labelledby="resume-label" />
</UploaderProvider>;

On this page