2024-06-28
In this blog we will learn how to disable the dialog trigger for a dialog when conditions are set.
Blog post by MF Mabala
Disabling the shadcn/ui dialog trigger
In my previous blogs we have explored using the shadcn dialog to be able to accept an invitation. The invitation status can either be accepted, rejected or pending. For best practices We will want to disable the buttons when the invitation has either been accepted or rejected . This will prevent the user from running the same action multiple times. Just to recap you can visit the following blog : https://madinku.dev/post/accepting-an-invitation-with-a-graphql-mutation
Take a look at the following code for the dialog that we used in the blog listed above this is the only file we will edit
import { useState } from 'react';
import { FieldValues, UseFormReturn } from 'react-hook-form';
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
Button,
Input,
DialogFooter,
Form,
FormField,
FormItem,
FormLabel,
FormControl,
FormMessage,
Loader,
} from '~/components/ui';
import { camelToTitleCase } from '~/lib/utils';
export function AcceptInviteDialog<T extends FieldValues>({
title,
description,
form,
formFields,
onSubmit,
loading,
}: AcceptInviteDialogProps<T>) {
return (
<div>
<Dialog>
<DialogTrigger>
<Button variant="outline" rounded="full">
{title}
</Button>
</DialogTrigger>
<DialogContent className="sm:max-w-[425px]">
<DialogHeader>
<DialogTitle>{title}</DialogTitle>
<DialogDescription>{description}</DialogDescription>
</DialogHeader>
<div className="grid gap-4 py-4">
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col w-full gap-8">
<div className="flex flex-col gap-2 w-full">
{formFields.map((key: any) => (
<FormField
key={key}
control={form.control}
name={key}
render={({ field }) => {
return (
<FormItem>
<FormLabel>{camelToTitleCase(key)}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
);
}}
/>
))}
</div>
<DialogFooter>
<Button type="submit" >
{loading ? 'Submitting..' : 'Accept Invite'}
</Button>
</DialogFooter>
</form>
</Form>
</div>
</DialogContent>
</Dialog>
</div>
);
}
interface AcceptInviteDialogProps<T extends FieldValues> {
title: string;
description: string;
loading: boolean;
form: UseFormReturn<T>;
formFields: readonly (keyof T)[];
onSubmit: (value: T) => void;
Now that you have an idea of how the dialog looks like. I am going to explain the logic I want to follow. The invitation can have a status of accepted, rejected and pending. When the status is not pending means that the invitation has already been accepted or rejected then in this case I want to disable the dialog trigger. this is how its done.
<DialogTrigger disabled={invitation?.status !== InvitationStatus.Pending}>
<Button variant="outline" rounded="full">
{title}
</Button>
</DialogTrigger>
You can updated the code by adding the above then it will work. The button will be disabled when the invitation status is not pending.