ui icon indicating copy to clipboard operation
ui copied to clipboard

I can't click anywhere after using alert dialog.

Open wCatly opened this issue 1 year ago • 5 comments

I wanted to implement alert-dialog into my dropdown menu but after I click to buttons I can't click anymore I had to refresh site.

code:

"use client"

import { ColumnDef } from "@tanstack/react-table"
import { ArrowUpDown, Eye, EyeOff, MoreHorizontal } from "lucide-react"

import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"

import {
    AlertDialog,
    AlertDialogAction,
    AlertDialogCancel,
    AlertDialogContent,
    AlertDialogDescription,
    AlertDialogFooter,
    AlertDialogHeader,
    AlertDialogTitle,
    AlertDialogTrigger,
  } from "@/components/ui/alert-dialog"

import { useRouter, useSearchParams } from "next/navigation"
import { useState } from "react"

export type Category = {
  id: string
  name: string
  products: number
  visibility: "public" | "private"
}



export const columns: ColumnDef<Category>[] = [
    
  {
    id: "select",
    header: ({ table }) => (
      <Checkbox
        checked={table.getIsAllPageRowsSelected()}
        onCheckedChange={(value:any) => table.toggleAllPageRowsSelected(!!value)}
        aria-label="Select all"
      />
    ),
    cell: ({ row }) => (
      <Checkbox
        checked={row.getIsSelected()}
        onCheckedChange={(value:any) => row.toggleSelected(!!value)}
        aria-label="Select row"
      />
    ),
    enableSorting: false,
    enableHiding: false,
  },
  {
    accessorKey: "name",
    header: "Kategori",
    cell: ({ row }) => <div>{row.getValue("name")}</div>,
  },
  {
    accessorKey: "products",
    header: "Ürün Sayısı",
    cell: ({ row }) => <div>{row.getValue("products")}</div>,
  },
  {
    accessorKey: "visibility",
    header: "Görünürlük",
    cell: ({ row }) => (
      <div>
        {row.getValue("visibility") === "public" ? 
          <><Eye className="mr-2 inline flex-1 text-sm text-muted-foreground" size={20}/>Herkese açık</> : 
          <><EyeOff className="mr-2 inline flex-1 text-sm text-muted-foreground" size={20}/>Gizli</>
        }
      </div>
    ),
  },
  {
    id: "actions",
    enableHiding: false,
    cell: ({ row }) => {
      const category = row.original
      // eslint-disable-next-line react-hooks/rules-of-hooks
      const router = useRouter()
      const handleDelete = () => {
        // Perform delete action here
        // For example:
        // deleteCategory(category.id)
        // .then(() => router.push('/categories'))
      }
      // eslint-disable-next-line react-hooks/rules-of-hooks
      const [isAlertDialogOpen, setAlertDialogOpen] = useState(false)
      
      return (
        <>
            <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button variant="ghost" className="h-8 w-8 p-0">
              <span className="sr-only">Open menu</span>
              <MoreHorizontal className="h-4 w-4" />
            </Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent align="end">
            <DropdownMenuLabel>Eylemler</DropdownMenuLabel>
            <DropdownMenuSeparator />
            


            <DropdownMenuItem onClick={() => setAlertDialogOpen(true)}>Kategoriyi Sil</DropdownMenuItem>

            <DropdownMenuItem onClick={() => router.push(`/categories/edit/${category.id}`)}>Katogori Görünürlük</DropdownMenuItem>
            
            <DropdownMenuSeparator />
            <DropdownMenuItem onClick={() => router.push(`/categories/edit/${category.id}`)}>Kategoriyi Düzenle</DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
        
        <AlertDialog open={isAlertDialogOpen} onOpenChange={setAlertDialogOpen}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Emin misiniz?</AlertDialogTitle>
            <AlertDialogDescription>
              Bu eylem geri alınamaz. Bu eylem kategoriyi kalıcı olarak silecek.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
          <AlertDialogCancel onClick={() => setAlertDialogOpen(false)}>İptal</AlertDialogCancel>
            <AlertDialogAction>Devam et</AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>

        </AlertDialog>
        </>
      )
      
    },
  },


]

wCatly avatar May 27 '23 11:05 wCatly

Me too I have the same issue.
I took the implementation from taxonomy, the dialog / dialog-alert inside a select will disable the click events exept for text selection :) after i close the dialog

abdullah-hallaq avatar May 30 '23 14:05 abdullah-hallaq

Hi @wCatly and @UnknownBigBrain, did you try this?

"To activate the Dialog component from within a Context Menu or Dropdown Menu, you must encase the Context Menu or Dropdown Menu component in the Dialog component. For more information, refer to the linked issue here."

From the documentation here: https://ui.shadcn.com/docs/components/dialog

samjowen avatar May 31 '23 21:05 samjowen

Hi @wCatly and @UnknownBigBrain, did you try this?

"To activate the Dialog component from within a Context Menu or Dropdown Menu, you must encase the Context Menu or Dropdown Menu component in the Dialog component. For more information, refer to the linked issue here."

From the documentation here: https://ui.shadcn.com/docs/components/dialog

Hi @samjowen thx for the response. Popover worked but Menu still have the same issue

Popover: `

    <Dialog open={showDeleteAlert} onOpenChange={setShowDeleteAlert}>
        <Popover open={open} onOpenChange={setOpen}>
            <PopoverTrigger className="flex h-8 w-8 items-center justify-center rounded-md border transition-colors hover:bg-muted">
                <Icons.ellipsis className="h-4 w-4" />
                <span className="sr-only">Open</span>
            </PopoverTrigger>

            <PopoverContent className="w-[200px] p-0">
                <Button
                    className="flex cursor-pointer items-center text-destructive focus:text-destructive"
                    onClick={() => setShowDeleteAlert(true)}
                >
                    Delete
                </Button>
            </PopoverContent>
        </Popover>
 

        <DialogContent>
            <DialogHeader>
                <DialogTitle>
                    Are you sure you want to delete this post?
                </DialogTitle>
                <DialogDescription>
                    This action cannot be undone.
                </DialogDescription>
            </DialogHeader>
            <DialogFooter>
                <DialogTrigger>Cancel</DialogTrigger>
                <DialogTrigger
                    onClick={async (event) => {
                        event.preventDefault();
                        setIsDeleteLoading(true);

                        // const deleted = await deletePost(post.id)

                        // if (deleted) {
                        setIsDeleteLoading(false);
                        setShowDeleteAlert(false);
                        router.refresh();
                        // }
                    }}
                    className="bg-red-600 focus:ring-red-600"
                >
                    {isDeleteLoading ? (
                        <Icons.spinner className="mr-2 h-4 w-4 animate-spin" />
                    ) : (
                        <Icons.trash className="mr-2 h-4 w-4" />
                    )}
                    <span>Delete</span>
                </DialogTrigger>
            </DialogFooter>
        </DialogContent>
    </Dialog>

`

Menu: `

 <Dialog open={showDeleteAlert} onOpenChange={setShowDeleteAlert}>
        <DropdownMenu>
            <DropdownMenuTrigger>
                <Icons.ellipsis className="h-4 w-4" />
                <span className="sr-only">Open</span>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end">
                <DropdownMenuItem>
                    <Link
                        href={`/editor/${product.id}`}
                        className="flex w-full"
                    >
                        Edit
                    </Link>
                </DropdownMenuItem>
                <DropdownMenuSeparator />
                <DropdownMenuItem
                    className="flex cursor-pointer items-center text-destructive focus:text-destructive"
                    onSelect={() => setShowDeleteAlert(true)}
                >
                    Delete
                </DropdownMenuItem>
            </DropdownMenuContent>
        </DropdownMenu>

        <DialogContent>
            <DialogHeader>
                <DialogTitle>
                    Are you sure you want to delete this post?
                </DialogTitle>
                <DialogDescription>
                    This action cannot be undone.
                </DialogDescription>
            </DialogHeader>
            <DialogFooter>
                <DialogTrigger>Cancel</DialogTrigger>
                <DialogTrigger
                    onClick={async (event) => {
                        event.preventDefault();
                        setIsDeleteLoading(true);

                        // const deleted = await deletePost(post.id)

                        // if (deleted) {
                        setIsDeleteLoading(false);
                        setShowDeleteAlert(false);
                        router.refresh();
                        // }
                    }}
                    className="bg-red-600 focus:ring-red-600"
                >
                    {isDeleteLoading ? (
                        <Icons.spinner className="mr-2 h-4 w-4 animate-spin" />
                    ) : (
                        <Icons.trash className="mr-2 h-4 w-4" />
                    )}
                    <span>Delete</span>
                </DialogTrigger>
            </DialogFooter>
        </DialogContent>
    </Dialog>

`

abdullah-hallaq avatar Jun 03 '23 06:06 abdullah-hallaq

'use client'
import { DropdownMenuTrigger } from '@radix-ui/react-dropdown-menu'
import { SlidersHorizontal } from 'lucide-react'
import { Button } from '@/components/ui/button'
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuItem,
} from '@/components/ui/dropdown-menu'
import { Dialog, DialogTrigger } from '@/components/ui/dialog'
import { AddGroupDialogContent } from '../../forms/components/add-group-dialog-content'
import { Sheet, SheetTrigger } from '@/components/ui/sheet'
import { AddItemSheetContent } from '../../forms/components/add-item-sheet-content'
import { EstimateType } from '@prisma/client'
import React from 'react'

export function AddItemsDropdown() {
  const [openSheet, setOpenSheet] = React.useState<boolean>(false)
  const [itemType, setItemType] = React.useState<EstimateType>('MATERIAL')
  return (
    <div>
      <Dialog>
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button variant='outline' size='sm' className='ml-auto hidden h-8 lg:flex'>
              <SlidersHorizontal className='mr-2 h-4 w-4' />
              Add Items
            </Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent align='end' className='w-[150px]'>
            <DropdownMenuLabel>Add Items</DropdownMenuLabel>
            <DialogTrigger className='w-full'>
              <DropdownMenuItem>{'Add Group'}</DropdownMenuItem>
            </DialogTrigger>
            <DropdownMenuItem
              onSelect={() => {
                setOpenSheet(true)
                document.body.style.pointerEvents = ""
              }}
            >
              {'Add Material'}
            </DropdownMenuItem>
            <DropdownMenuSeparator />
          </DropdownMenuContent>
        </DropdownMenu>
        <AddGroupDialogContent />
      </Dialog>
      <Sheet open={openSheet} onOpenChange={setOpenSheet}>
        <SheetTrigger>
          <Button>{'Open'}</Button>
        </SheetTrigger>
        <AddItemSheetContent type={itemType} />
      </Sheet>
    </div>
  )
}

In my case it appears that when i open my sheet within a DropdownMenuItem and closing the sheet afterwards the pointer event on the body remains none my fix was using document.body.style.pointerEvents = ""

Angulo66 avatar Jun 04 '23 19:06 Angulo66

To add to prev answer: the consistent way is to modify the DialogPrimitive.Close component. You have to do the setTimeout. It's not great, happy to make a PR to issue a fix but I'm not exactly sure what the better solution is @shadcn

<DialogPrimitive.Close
        className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground"
        onClick={() => {
          // yes, you have to set a timeout
          setTimeout(() => (document.body.style.pointerEvents = ""), 500);
        }}
      >
        <X className="h-4 w-4" />
        <span className="sr-only">Close</span>
      </DialogPrimitive.Close>

ataki avatar Jun 26 '23 15:06 ataki

Any update on this?

holy-dev avatar Jul 18 '23 06:07 holy-dev

 <DropdownMenu>
  <DropdownMenuTrigger asChild={true}>
    <Button variant="ghost" className="h-8 w-8 p-0">
      <span className="sr-only">Open Menu</span>
      <span className="h-4 w-4">
        <MoreHorizontal />
      </span> </Button>
  </DropdownMenuTrigger>
  <DropdownMenuContent align="end">
    <DropdownMenuLabel>Actions</DropdownMenuLabel>
    <AlertDialog>
      <AlertDialogTrigger asChild>
        <DropdownMenuItem
          className="bg-green-500 hover:bg-green-700 hover:text-white"
          onSelect={(e) => e.preventDefault()}
        >
          <Eye className="w-4 h-4 mr-2" /> Show Detail
        </DropdownMenuItem>
      </AlertDialogTrigger>
      <AlertDialogContent>
        <AlertDialogHeader>
          <AlertDialogTitle>
            Are you sure?
          </AlertDialogTitle>
          <AlertDialogDescription>
            Hahahahaha
          </AlertDialogDescription>
        </AlertDialogHeader>
        <AlertDialogFooter>
          <AlertDialogCancel>Cancel</AlertDialogCancel>
          <AlertDialogAction>Continue</AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
    <DropdownMenuItem className="bg-yellow-500 hover:bg-yellow-700 hover:text-white">
      <Pencil className="w-4 h-4 mr-2" /> Edit
    </DropdownMenuItem>
    <DropdownMenuItem className="bg-red-500 text-white hover:bg-red-700">
      <Trash className="w-4 h-4 mr-2" /> Delete
    </DropdownMenuItem>
  </DropdownMenuContent>
</DropdownMenu >

if you still have this problem, you can try using this code, i manage to open alert dialog inside the dropdown menu

prawpash avatar Aug 18 '23 02:08 prawpash

This trick worked.

https://github.com/radix-ui/primitives/issues/1836#issuecomment-1674338372

you may also want to disable the modal of DropdownMenu by setting the value to false.

makelsevilla avatar Sep 29 '23 18:09 makelsevilla

If it helps anyone, ran into the same problem and inspired by the comments above I solved it using this:

<AlertDialog
    open={deleteDialogOpen}
    onOpenChange={() => { setTimeout(() => (document.body.style.pointerEvents = ""), 100) }}
>

Seems to be working well so for now.

jad-eljerdy avatar Oct 12 '23 17:10 jad-eljerdy

In my case l've got that error because on my dialog component I've imported by error this line of code import { DialogDescription } from '@radix-ui/react-dialog' instead of import { DialogDescription } from './ui/dialog'. Once I've changed it back it works as it should.

braian-bernatto avatar Nov 12 '23 15:11 braian-bernatto

Thanks for the updates @braian-bernatto

shadcn avatar Nov 12 '23 18:11 shadcn

Setting <DropdownMenu modal={false}> solved the problem bcs i had two modal in place.

If it helps anyone, ran into the same problem and inspired by the comments above I solved it using this:

<AlertDialog
    open={deleteDialogOpen}
    onOpenChange={() => { setTimeout(() => (document.body.style.pointerEvents = ""), 100) }}
>

Seems to be working well so for now.

Kiranism avatar Feb 13 '24 07:02 Kiranism

Thanks @Kiranism ! I was using a Dropdown with a Button trigger. DropdownItems was opening a modal. After closing that modal anything was not clickable anymore. Setting modal={false} solved the issue.

bakikucukcakiroglu avatar Jun 18 '24 11:06 bakikucukcakiroglu

here's what i found to solve:

  1. update @radix-ui/react-dropdown-menu to 2.1.1
  2. set modal={false} on DropdownMenu

hope it helps.

dalalRohit avatar Jul 16 '24 10:07 dalalRohit

Thanks @dalalRohit! Solved the modal and dropdown menu problem :) Another problem I was having was when using a Popover inside the modal inside the dropdownmenu, which I also managed to solve by putting modal={true} in the Popover.

nataliamanosso avatar Jul 17 '24 13:07 nataliamanosso

here's what i found to solve:

  1. update @radix-ui/react-dropdown-menu to 2.1.1
  2. set modal={false} on DropdownMenu

hope it helps.

only second option worked on me, thanks @dalalRohit

nh-tu-z avatar Jul 24 '24 07:07 nh-tu-z

if you are using any popover/alertdialog/modal inside dropdown-menu set the modal=false on DropdownMenu fixes this issue

<DropdownMenu modal={false}>

iamrishan avatar Aug 08 '24 10:08 iamrishan