/** * A form's file field. * * @module */ import { Controller, type FieldValues, type Path, type RegisterOptions, useFormContext, } from "react-hook-form"; import { FileDropZone } from "./FileDropZone.tsx"; /** The props of {@link FileField}. */ export interface FileFieldProps { /** The field's name in the form. */ name: Path; /** The field's label. */ label?: string; /** The drop zone's prompt. */ hint?: string; /** Whether to state the size limit. */ showLimit?: boolean; /** Whether the field takes no file. */ disabled?: boolean; /** The field's validation rules. */ rules?: RegisterOptions>; /** Side effect run after the field value changes (e.g. derive a title). */ onValueChange?: (file: File | null) => void; } /** * Renders a `Controller`-wrapped {@link FileDropZone} bound to react-hook-form, * with the field's error under it. */ export function FileField({ name, label, hint, showLimit, disabled, rules, onValueChange, }: FileFieldProps): React.JSX.Element { const { control, formState: { errors } } = useFormContext(); const error = errors[name]; return (
{label && {label}} ( { field.onChange(file); onValueChange?.(file); }} hint={hint} showLimit={showLimit} disabled={disabled} /> )} /> {error?.message && ( {String(error.message)} )}
); }