shadcn-ui / ui

Beautifully designed components that you can copy and paste into your apps. Accessible. Customizable. Open Source.
https://ui.shadcn.com
MIT License
70.75k stars 4.25k forks source link

Trigger State Change When Dialog Is Closed #2573

Closed Existential-Critic closed 8 months ago

Existential-Critic commented 8 months ago

Hello,

I am trying to create a dynamic dialog window using Shadcn's UI. The dialog is a sign in window, which has 3 states: Sign In, Forgot Password, and Sign Up. When the dialog is opened, it should default to state 1, Sign In, and only change to state 2 or 3 (Forgot Password and Sign Up respectively) if the user clicks the buttons inside the dialog to change state.

However, when I close the dialog and go back to it, it stays on whichever state it was last on instead of reverting to state 1. How do I trigger the state resetting to 1 when the dialog window is closed?

const [dialogState, setDialogState] = useState(1);


          <Dialog open={showSignInDialog} onOpenChange={setShowSignInDialog}>
            <DialogTrigger asChild>
              <Button>
                <span className="font-bold text-base">Sign In</span>
              </Button>
            </DialogTrigger>
            {dialogState === 1 && (
              <DialogContent id="signInDialog" className="sm:max-w-[300px]">
                <DialogHeader>
                  <DialogTitle className="text-center">Sign In</DialogTitle>
                </DialogHeader>
                <div className="flex flex-col w-full items-center">
                  <div id="googleSignIn" className="pb-2">
                    <Button
                      className="h-40px bg-white dark:bg-[#131314] border-[#747775] dark:border-[#8E918F] border-[1px] text-[#1F1F1F] dark:text-[#E3E3E3] text-sm font-roboto font-medium px-3 py-2.5 hover:bg-transparent"
                      onClick={SignIn}
                    >
                      <Image
                        src="/Google_Logo.svg"
                        alt="google"
                        width={20}
                        height={20}
                      />
                      <span className="pl-2.5">Sign in with Google</span>
                    </Button>
                  </div>
                  <div id="signInSeparator" className="relative pb-2">
                    <div className="relative flex justify-center text-xs uppercase">
                      <span className="bg-background px-2 text-muted-foreground">
                        Or
                      </span>
                    </div>
                  </div>
                  <div id="emailSignIn" className="grid gap-1.5">
                    <Input
                      placeholder="Email Address *"
                      className="pb-2"
                    ></Input>
                    <Input placeholder="Password *"></Input>
                    <Button className="w-full">
                      <span>Sign in with Email</span>
                    </Button>
                    <Button
                      className="bg-background text-primary text-xs justify-self-center hover:bg-transparent shadow-none h-3/4"
                      onClick={() => setDialogState(2)}
                    >
                      Forgot your password?
                    </Button>
                  </div>
                  <hr className="w-3/4 bg-gray-500" />
                  <div id="signUpConnector" className="w-3/4 text-center">
                    <Button
                      className="bg-background text-primary text-xs justify-self-center hover:bg-transparent shadow-none h-3/4"
                      onClick={() => setDialogState(3)}
                    >
                      Create New Account
                    </Button>
                  </div>
                </div>
              </DialogContent>
            )}
            {dialogState === 2 && (
              <DialogContent className="sm:max-w-[300px]">
                <DialogHeader>
                  <DialogTitle className="text-center">
                    Forgot Password
                  </DialogTitle>
                </DialogHeader>
                <div className="flex flex-col w-full items-center">
                  <div id="emailLogin" className="grid gap-1.5">
                    <Input
                      placeholder="Email Address *"
                      className="pb-2"
                    ></Input>
                    <Button className="w-full">
                      <span>Send Reset Email</span>
                    </Button>
                  </div>
                  <hr className="w-3/4 bg-gray-500" />
                  <div id="signInConnector" className="w-3/4 text-center">
                    <Button
                      className="bg-background text-primary text-xs justify-self-center hover:bg-transparent shadow-none h-3/4"
                      onClick={() => setDialogState(1)}
                    >
                      Sign in to your account
                    </Button>
                  </div>
                </div>
              </DialogContent>
            )}
            {dialogState === 3 && (
              <DialogContent className="sm:max-w-[300px]">
                <DialogHeader>
                  <DialogTitle className="text-center">Sign Up</DialogTitle>
                </DialogHeader>
                <div className="flex flex-col w-full items-center">
                  <div id="googleSignUp" className="pb-2">
                    <Button
                      className="h-40px bg-white dark:bg-[#131314] border-[#747775] dark:border-[#8E918F] border-[1px] text-[#1F1F1F] dark:text-[#E3E3E3] text-sm font-roboto font-medium px-3 py-2.5 hover:bg-transparent"
                      onClick={SignIn}
                    >
                      <Image
                        src="/Google_Logo.svg"
                        alt="google"
                        width={20}
                        height={20}
                      />
                      <span className="pl-2.5">Sign up with Google</span>
                    </Button>
                  </div>
                  <div id="signUpSeparator" className="relative pb-2">
                    <div className="relative flex justify-center text-xs uppercase">
                      <span className="bg-background px-2 text-muted-foreground">
                        Or continue with
                      </span>
                    </div>
                  </div>
                  <div id="emailSignUp" className="grid gap-1.5 pb-2">
                    <Input placeholder="Email Address *"></Input>
                    <Input placeholder="Confirm Email Address *"></Input>
                    <Input placeholder="Password *"></Input>
                    <Input placeholder="Confirm Password *"></Input>
                    <Button className="w-full">
                      <span>Sign up with Email</span>
                    </Button>
                  </div>
                  <hr className="w-3/4 bg-gray-500" />
                  <div id="signInConnector" className="w-3/4 text-center">
                    <Button
                      className="bg-background text-primary text-xs justify-self-center hover:bg-transparent shadow-none h-3/4"
                      onClick={() => setDialogState(1)}
                    >
                      Sign in to your account
                    </Button>
                  </div>
                </div>
              </DialogContent>
            )}
          </Dialog>
        </div>```
imopbuilder commented 8 months ago

@Existential-Critic

You can use onCloseAutoFocus event on the DialogContent component to update the state to the desired value

export function DialogDemo() {
    return (
        <Dialog>
            <DialogTrigger>Open</DialogTrigger>
            <DialogContent onCloseAutoFocus={() => console.log('closed')}>
                <DialogHeader>
                    <DialogTitle>Are you absolutely sure?</DialogTitle>
                    <DialogDescription>
                        This action cannot be undone. This will permanently delete your account and remove your data from our servers.
                    </DialogDescription>
                </DialogHeader>
            </DialogContent>
        </Dialog>
    );
}

https://github.com/shadcn-ui/ui/assets/150527559/94048b50-4a30-49f4-bcc4-c4f37dc17fef

Existential-Critic commented 8 months ago

This worked perfectly, thank you!