ui: Type conflicts in forms with file inputs
I wanted to implement a form where users should submit the pdf file, but I keep getting the conflicts in Input props.
I tried to extend the InputProps in ui/input.tsx, but with no success
For now, I only found a solution that passes the pdf as z.any() and it passes as a string with fakepath to the values. I wanted to pass the File object to then use it on the backend
"use client";
import { zodResolver } from "@hookform/resolvers/zod";
import * as z from "zod";
import { Button } from "@/components/ui/button";
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { useForm } from "react-hook-form";
const MAX_SIZE_MB = 1;
const formSchema = z.object({
pdf: z
.custom<FileList>()
.transform((file) => file.length > 0 && file.item(0))
.refine(
(file) => !file || (!!file && file.size <= MAX_SIZE_MB * 1024 * 1024),
{
message: `The profile picture must be a maximum of ${MAX_SIZE_MB}MB.`,
}
)
.refine(
(file) => !file || (!!file && file.type?.startsWith("application/pdf")),
{
message: "Only PDFs are allowed to be sent.",
}
),
});
export function VerifyForm() {
// 1. Define your form.
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
pdf: null,
},
});
// 2. Define a submit handler.
function onSubmit(values: z.infer<typeof formSchema>) {
// Do something with the form values.
// ✅ This will be type-safe and validated.
console.log(values);
}
return (
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="space-y-8"
>
<FormField
control={form.control}
name="pdf"
render={({ field }) => (
<FormItem>
<FormLabel>Student Card</FormLabel>
<FormControl>
<Input
type="file"
accept=".pdf"
placeholder="StudentCard.pdf"
{...field}
/>
</FormControl>
<FormDescription>
This is used to get your University and Course year
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
</form>
</Form>
);
}
About this issue
- Original URL
- State: open
- Created a year ago
- Reactions: 7
- Comments: 15
I have found a solution to this. This way worked for me. For the code I wrote below, if you upload the files more than once, the old files are still there. If you don’t want your old files, you can just use
onChange={(event) => onChange(event.target.files)}for the onChange field in the <FormControl>.EDIT: https://github.com/shadcn-ui/ui/issues/884#issuecomment-1847473190 I forgot to get the current images value, so the previous code doesn’t work (I think I accidentally deleted it).
I’ve edited the source code I provided below. But then again, If you don’t want your previous files, you won’t need to get the current value of images, just use the
onChange={(event) => onChange(event.target.files)}.Some solution for this? or better use another Input (drop-zone) or custom