53 lines
1.4 KiB
TypeScript
Raw Normal View History

2022-05-06 21:05:02 -04:00
import { ReactNode, PropsWithoutRef } from "react"
import { Form as FinalForm, FormProps as FinalFormProps } from "react-final-form"
import { z } from "zod"
import { validateZodSchema } from "blitz"
export { FORM_ERROR } from "final-form"
export interface FormProps<S extends z.ZodType<any, any>>
extends Omit<PropsWithoutRef<JSX.IntrinsicElements["form"]>, "onSubmit"> {
/** All your form fields */
children?: ReactNode
/** Text to display in the submit button */
submitText?: string
schema?: S
onSubmit: FinalFormProps<z.infer<S>>["onSubmit"]
initialValues?: FinalFormProps<z.infer<S>>["initialValues"]
}
export function Form<S extends z.ZodType<any, any>>({
children,
submitText,
schema,
initialValues,
onSubmit,
...props
}: FormProps<S>) {
return (
<FinalForm
initialValues={initialValues}
validate={validateZodSchema(schema)}
onSubmit={onSubmit}
render={({ handleSubmit, submitting, submitError }) => (
<form onSubmit={handleSubmit} className="form" {...props}>
{/* Form fields supplied as children are rendered here */}
{children}
{submitError && (
<div role="alert" style={{ color: "red" }}>
{submitError}
</div>
)}
{submitText && (
<button type="submit" disabled={submitting}>
{submitText}
</button>
)}
</form>
)}
/>
)
}
export default Form