Help with a form inside a compound component (React)
Unanswered
Spectacled bear posted this in #help-forum
Spectacled bearOP
Hi everyone, I’m working on a UI where I use a compound components pattern (Sheet + SheetHeader + SheetContent + SheetFooter). One of the child components, <IntegrationCredentialsForm />, contains a <form>.
In the design, the submit button lives outside the <form> (in the sheet footer), so I’m binding submit with a form ID (<Button form={formId} type="submit">).
Everything works, but now I want to:
Disable the submit button when the form is invalid
Keep the current layout (submit button outside the actual form)
Support not only this form but potentially other future forms inside the sheet
The issue is that the parent doesn’t have access to the form state (valid/invalid) from inside IntegrationCredentialsForm.
Here’s the relevant snippet:
My question is:
How can I disable the submit button in the sheet footer based on the children form’s validity, given that the form is inside the sheet content and the submit button is outside of it?
I’m looking for a scalable approach (e.g., context, forwarding state, hooks, etc.) since this pattern may apply to future forms too.
Thanks in advance!
In the design, the submit button lives outside the <form> (in the sheet footer), so I’m binding submit with a form ID (<Button form={formId} type="submit">).
Everything works, but now I want to:
Disable the submit button when the form is invalid
Keep the current layout (submit button outside the actual form)
Support not only this form but potentially other future forms inside the sheet
The issue is that the parent doesn’t have access to the form state (valid/invalid) from inside IntegrationCredentialsForm.
Here’s the relevant snippet:
<SheetContent className="px-4 sm:max-w-md">
...
{config.auth?.type = AuthType.Credentials ? (
<IntegrationCredentialsForm config={config} formId={formId} />
) : (
<Empty>…</Empty>
)}
...
<SheetFooter>
<DialogClose asChild>
<Button variant="outline">Cancel</Button>
</DialogClose>
<DialogClose asChild>
<Button form={formId} type="submit">
Save Changes
</Button>
</DialogClose>
</SheetFooter>
</SheetContent>My question is:
How can I disable the submit button in the sheet footer based on the children form’s validity, given that the form is inside the sheet content and the submit button is outside of it?
I’m looking for a scalable approach (e.g., context, forwarding state, hooks, etc.) since this pattern may apply to future forms too.
Thanks in advance!
5 Replies
Longtail tuna
if you are using tanstack form then wrap both form and submit button within given form context
What I would do is just keep the form state in this "parent component" which includes the sheet, and this
Something like this:
IntegrationCredentialsForm and possibly other forms in future which will exist in this sheet too? Something like this:
export const ParentComponent() {
const form1 = useForm();
const form2 = useForm();
const form3 = useForm();
return (
<Sheet>
<Form1 state={form1} />
<Form2 state={form2} />
<Form3 state={form3} />
<Button disabled={form1.isValid && form2.isValid && form3.isValid}>
Submit
</Button>
</Sheet>
)
}Longtail tuna
you can even abstract that by creating
SubmitButton or something in createFormHookthen in
SubmitButton youd do const form = useFormContext() and set disabled prop as necessary in ur caseSpectacled bearOP
alright thanks guys