# Shadcn: the Dialog closes when you open it from a Dropdown

The Radix menu unmounts the item and returns focus while the dialog opens. Here are three fixes, each with its own trade-off.

> Page: https://ui.eneawork.it/blog/shadcn-dialog-si-chiude-da-dropdown
> Markdown: https://ui.eneawork.it/blog/shadcn-dialog-si-chiude-da-dropdown.md

*2026-11-01*

Risposta breve: il menu chiude la voce che hai cliccato e smonta il subtree in cui vive il dialog. Tieni il <Dialog> fuori dal <DropdownMenu> e controllane l'apertura con uno stato: è la correzione che non lascia effetti collaterali.

La domanda specifica non ha un punteggio alto su Stack Overflow; la misura disponibile è il volume del tema: 8.264 domande con tag accessibility e 475.168 con tag react sulla Stack Exchange API al 31 ottobre 2026. Il catalogo EneUI misura 111.985 componenti, 1.556 blocchi, 12.808 icone da 1.472 librerie, valori misurati e letti da /api/stats il 1 novembre 2026. Le prove si fanno da tastiera, sul componente già in pagina.

## Cosa succede, passo per passo

Il risultato visibile è un dialog che appare per un frame e sparisce, oppure che non appare affatto.

## Perché la voce sparisce

Il DropdownMenuContent di Radix non resta nel DOM quando il menu è chiuso: usa una presence che monta il contenuto all'apertura e lo smonta a chiusura completata. Il Dialog scritto dentro una DropdownMenuItem è quindi figlio di un nodo che sta per sparire. Radix chiude il menu al click, restituisce il focus al trigger con onCloseAutoFocus e smonta il contenuto: il dialog se ne va con lui, anche se il suo stato è ancora aperto.

Il menu è anche modale per impostazione predefinita. Mentre è aperto, Radix applica pointer-events: none al resto del documento e intrappola il focus nel contenuto. Sono due comportamenti indipendenti dalla smontatura, e la seconda parte spiega perché alcune correzioni sembrano funzionare e poi bloccano i click.

## La correzione pulita: stato fuori dal menu

"use client"; import { useState } from "react"; import { DropdownMenu, DropdownMenuItem, DropdownMenuTrigger, DropdownMenuContent } from "@/components/ui/dropdown-menu"; import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog"; export function RowActions() { const [open, setOpen] = useState(false); return ( <> Azioni setOpen(true)}> Rinomina Rinomina ); }

I due componenti sono fratelli: la chiusura del menu non tocca il dialog. È anche il modo più semplice da testare, perché lo stato è uno solo.

## Le alternative, con il loro costo

## Il passo diagnostico

{ // when the close comes from focus return, this fires right after the open console.log("dialog", next, new Error().stack); setOpen(next); }} >

Apri il dialog da tastiera con Invio e leggi la sequenza. Se vedi true seguito da false nello stesso tick, la chiusura arriva dal ritorno del focus e non da uno smontaggio: la traccia dello stack indica quale gestore l'ha innescata. Se onOpenChange viene chiamato una volta sola con true e il dialog non compare, il problema è a monte, nel ramo che lo renderizza.

## Quando la correzione non funziona

Se il dialog continua a chiudersi, il problema può essere un onOpenChange che riceve false dal focus esterno: quando il menu restituisce il focus, Radix può interpretarlo come click fuori. In quel caso apri il dialog dopo il completo smontaggio del menu, per esempio con requestAnimationFrame nel gestore, oppure con onCloseAutoFocus sul menu.

## Quando la correzione comune peggiora le cose

La correzione più citata è e.preventDefault() su onSelect: impedisce la chiusura della voce e lascia il menu aperto. Con il menu modale, però, il pointer-events: none sul resto della pagina resta attivo, quindi il dialog appare ma non risponde al mouse: i pulsanti non si premono e il campo di testo non prende il focus. Il sintomo cambia da «il dialog si chiude» a «il dialog non si usa», ed è più difficile da collegare alla causa. Chi reagisce aggiungendo modal=&#123;false&#125; al menu perde la trappola del focus, e il Tab esce dal menu mentre il dialog è aperto.

## Un limite con un nome

Limite dichiarato del rimedio con requestAnimationFrame: non ha un evento su cui agganciarsi. Aspetta un frame, non la fine dell'animazione di uscita del menu, quindi con un'animazione più lunga o un dispositivo lento il dialog si apre mentre il contenuto del menu è ancora montato, e la chiusura ritorna. Funziona, ma in modo probabilistico: il rimedio affidabile resta spostare il dialog fuori dal menu, dove l'ordine dei montaggi non conta.

## Come prevenirlo

## Dove continuare

Nel catalogo: dialog block con preview, sidebar con menu annidati e tutti i blocchi. Le guide: i migliori dialog block misurati e checklist di accessibilità; il confronto: Radix, Base UI e React Aria.

## FAQ

### Perché il dialog si apre e si chiude subito?

Il menu chiude la propria voce, restituisce il focus e smonta il subtree in cui vive il dialog. Il dialog viene smontato insieme al resto.

### `e.preventDefault()` su onSelect è sufficiente?

Sblocca il caso più comune, ma lascia il menu aperto sotto. Per un dialog modale è meglio spostare il Dialog fuori dal menu.

### `modal={false}` sul DropdownMenu aiuta?

Sì nei casi in cui il problema è il blocco dello scroll e la gestione del focus, ma perdi il comportamento modale del menu: valuta il compromesso.

### Succede anche con Popover?

Sì, ogni primitiva che smonta il contenuto alla chiusura. La regola è la stessa: controlla lo stato del dialog dall'esterno.

### Come verifico che il dialog abbia il focus giusto?

Apri da tastiera, premi Tab e controlla che il focus resti dentro il dialog. Poi chiudi con Esc e verifica che torni sulla voce del menu.
