Verify and upload4 checks
FormFile
Drop zone with type, size and count rules.
Example
Installation
bunx --bun shadcn@latest add @fieldkit/form-fileNeeds the @fieldkit registry. Add it once
Usage
- 1
Add the field to your schema
schema.tsimport { z } from "zod"import { fileField } from "@/lib/field-schemas" export const schema = z.object({ cv: fileField({ accept: { "application/pdf": [".pdf"] }, maxSize: 5 * 1024 * 1024 }),}) - 2
Render it inside a Form
The name prop matches the schema key.
example-form.tsximport { Form } from "@/components/form/form"import { FormFile } from "@/components/form/form-file"import { FormSubmit } from "@/components/form/form-submit"import { FieldGroup } from "@/components/ui/field"import { schema } from "./schema" export function ExampleForm() { return ( <Form schema={schema} defaultValues={{ cv: [] }} onSubmit={save} > <FieldGroup> <FormFile name="cv" /> <FormSubmit>Save</FormSubmit> </FieldGroup> </Form> )}
Checks
CheckOptionError message
Required
minChoose a fileFile type
acceptcv.docx is not a supported file typeSize
maxSizecv.pdf is over 5 MB. Choose a smaller file.Number of files
maxFilesUpload up to 3 filesBest practices
- Pass existing and onRemoveExisting to show saved files when editing
- Check the type again on the server
Try these values
Terminal
fileField({ accept: { "application/pdf": [".pdf"] }, maxSize: 1024 })| Input | Result | Output |
|---|---|---|
["cv.pdf, 512 B"] | Valid | ["cv.pdf, 512 B"] |
["big.pdf, 2048 B"] | Invalid | One of the files is too large |
[] | Invalid | Choose a file |
API reference
FormFile
PropDescription
acceptFileAcceptFile types, as words or MIME map.existingArray<{ id, name, url?, type? }>Files already saved, for edit forms.onRemoveExisting(id: string) => voidCalled when a saved file is removed.Field frame
PropDescription
namestringKey in the schema. Also picks the preset label and autocomplete.labelReact.ReactNodeOverrides the preset label. Pass null to hide it.descriptionReact.ReactNodeHint under the control.requiredbooleanOverrides the asterisk read from the schema.fieldPropsFormFieldPropsProps for the wrapping Field, such as className.