nextui-org/nextui

[BUG] - Double button click

Closed this issue · 3 comments

NextUI Version

2.4.8

Describe the bug

i am using terminary operator to display different button but both getting clicked

Your Example Website or App

No response

Steps to Reproduce the Bug or Issue

use similar code like below

"use client";
import EditTwoToneIcon from "@mui/icons-material/EditTwoTone";
import SaveTwoToneIcon from "@mui/icons-material/SaveTwoTone";
import { Input } from "@nextui-org/input";
import { Button, Chip } from "@nextui-org/react";
import { useEffect, useState } from "react";
import { Controller, useForm } from "react-hook-form";
import { api } from "~/trpc/react";

interface AddUPIProps {
  upiId: string | null | undefined;
}

export default function AddUPI({ upiId }: AddUPIProps) {
  const {
    register,
    handleSubmit,
    setValue,
    formState: { isSubmitting, errors },
    reset,
    setFocus,
    control,
  } = useForm({
    defaultValues: {
      upi: upiId ?? "",
    },
  });

  const apiUtils = api.useUtils();
  const updateUPI = api.wallet.updateUPI.useMutation({
    onSuccess: (data, variables) => {
      setIsEditing(false);
      setValue("upi", variables.upiId);
    },
    onSettled: () => {
      apiUtils.wallet.getWallet.invalidate().catch(console.error);
    },
  });

  const [isEditing, setIsEditing] = useState(false);

  const onSubmit = (data: { upi: string | null | undefined }) => {
    if (data.upi) updateUPI.mutate({ upiId: data.upi });
  };

  useEffect(() => {
    if (upiId) {
      reset({ upi: upiId });
    }
  }, [upiId, reset]);

  useEffect(() => {
    if (errors.upi && isEditing) {
      setFocus("upi", { shouldSelect: true });
    }
  }, [errors, setFocus, isEditing]);

  return (
    <form className="h-full" onSubmit={handleSubmit(onSubmit)}>
      <Chip
        variant="light"
        className="h-full"
        endContent={
          !isEditing ? (
            <Button type="button" isIconOnly onPress={() => setIsEditing(true)}>
              <EditTwoToneIcon />
            </Button>
          ) : (
            <Button type="submit" isIconOnly isLoading={updateUPI.isPending} isDisabled={updateUPI.isPending}>
              <SaveTwoToneIcon />
            </Button>
          )
        }
      >
        <Controller
          control={control}
          rules={{
            required: "UPI ID is required",
            validate: {
              includesAt: (value) => value.includes("@") || "UPI ID must include '@'",
              minLength: (value) => value.length >= 3 || "UPI ID must be at least 3 characters long",
            },
          }}
          render={({ field: { onChange, onBlur, value } }) => (
            <Input
              isDisabled={updateUPI.isPending || isSubmitting || !isEditing}
              placeholder="Add UPI ID"
              className="h-full text-foreground"
              color={errors.upi ? "danger" : "success"}
              isInvalid={!!errors.upi}
              errorMessage={errors.upi?.message}
              variant="bordered"
              autoComplete="off"
              fullWidth
              isClearable
              onBlur={onBlur}
              onChange={onChange}
              value={value}
            />
          )}
          name="upi"
        />
      </Chip>
    </form>
  );
}

Expected behavior

it should not click both buttons inside endContent

Screenshots or Videos

No response

Operating System Version

windows

Browser

Chrome

using workaround like this:

 endContent={
          !isEditing ? (
            <Button type="button" isIconOnly onPress={() => setTimeout(() => setIsEditing(true), 0)}>
              <EditTwoToneIcon />
            </Button>
          ) : (
            <Button type="submit" isIconOnly isLoading={updateUPI.isPending} isDisabled={updateUPI.isPending}>
              <SaveTwoToneIcon />
            </Button>
          )
        }

it should not click both buttons inside endContent

This is introduced from your logic. After the first click, isEditing is set to true and the second button is displayed. Your second click is on the second button.