Search code examples
reactjsreact-hook-formzodshadcnui

Shadcn/ui Tooltip around Button causes form validation


I'm using the Form component from Shadcn/ui to create a form which also uses react-hook-form and zod. In this form I have a button called Button 1 which has a Shadcn/ui Tooltip. The idea behind this is that the user clicks Button 1, and the string "Button 1" is stored into the form. Here's the code:

export default function JobForm() {
  const formSchema = z.object({
    jobName: z.string().min(1).max(50),
    button: z.string().optional(),
  });

  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      jobName: "",
      button: "",
    },
  });

  function onSubmit(values: z.infer<typeof formSchema>) {
    console.log(values);
  }
  
  return (
    <div>
      <Form {...form}>
        <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
          <FormField
            control={form.control}
            name="jobName"
            render={({ field }) => (
              <FormItem>
                <FormLabel>Job Name</FormLabel>
                <FormControl>
                  <Input placeholder="Input job name" {...field} />
                </FormControl>
                <FormMessage />
              </FormItem>
            )}
          />
          <Controller
            name="button"
            control={form.control}
            render={({ field }) => (
              <FormItem>
                <FormLabel>Button</FormLabel>
                <FormControl>
                  <TooltipProvider>
                    <Tooltip>
                      <TooltipTrigger>
                        <Button
                          type="button"
                          className="mr-2"
                          onClick={() => form.setValue('button', "Button 1")}
                        >
                          Button 1
                        </Button>
                      </TooltipTrigger>
                      <TooltipContent>
                        <p>"This is Button 1"</p>
                      </TooltipContent>
                    </Tooltip>
                  </TooltipProvider>
                </FormControl>
                <FormMessage />
              </FormItem>
            )}
          />
          <Button type="submit">Submit</Button>
        </form>
      </Form>
    </div>
  );
}

The issue is that clicking Button 1 triggers a validation on the job name field. I only want the submit button to trigger validation. I think it's the Tooltip causing the issue, since removing the Tooltip around Button 1 fixes the issue. How can I have a Tooltip component around Button 1 without causing validation on click?


Solution

  • You need to include asChild in ToolTipTrigger

    <TooltipTrigger asChild> {/* Add asChild here */}
      <Button
        type="button"
        className="mr-2"
        onClick={() => handleButtonClick('Button 1')}
      >
        Button 1
      </Button>
    </TooltipTrigger>
    

    From the docs, ToolTipTrigger is rendered as a button by default, and so clicking on the component inside ToolTipTrigger will act as clicking on a button, which therefore causes validation if the button's type is not set to button.