From a045e3a0f97b0b3a87a60efba061ffdb895cc41d Mon Sep 17 00:00:00 2001 From: Lukas Date: Fri, 19 Jun 2026 16:52:17 +0200 Subject: [PATCH] Unmount Dialog children when closed The native wrapper rendered its children unconditionally and only called dialog.close() on the underlying element when open went false. The React subtree stayed mounted, so component state (e.g. a ConfirmButton mid-confirm with a red checkmark showing) survived a close/reopen cycle and reappeared the next time the user opened the same dialog. Gate children on open so the subtree unmounts on close. Next open gets a fresh tree with default state. --- .../web/src/components/__tests__/dialog.test.tsx | 16 ++++++++++++++++ apps/web/src/components/ui/dialog.tsx | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/apps/web/src/components/__tests__/dialog.test.tsx b/apps/web/src/components/__tests__/dialog.test.tsx index 719f791..fcda051 100644 --- a/apps/web/src/components/__tests__/dialog.test.tsx +++ b/apps/web/src/components/__tests__/dialog.test.tsx @@ -38,6 +38,22 @@ describe("Dialog", () => { expect(dialog?.hasAttribute("open")).toBe(false); }); + it("unmounts children when closed so internal state does not persist", () => { + const { rerender } = render( + {}}> + Body + , + ); + expect(screen.queryByText("Body")).not.toBeNull(); + + rerender( + {}}> + Body + , + ); + expect(screen.queryByText("Body")).toBeNull(); + }); + it("calls onClose on cancel event", () => { const onClose = vi.fn(); render( diff --git a/apps/web/src/components/ui/dialog.tsx b/apps/web/src/components/ui/dialog.tsx index fcd80b2..de634a2 100644 --- a/apps/web/src/components/ui/dialog.tsx +++ b/apps/web/src/components/ui/dialog.tsx @@ -46,7 +46,7 @@ export function Dialog({ open, onClose, className, children }: DialogProps) { className, )} > -
{children}
+ {open ?
{children}
: null}
); }