Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/code-components/Combobox/Combobox.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@
.positioner {
transition: opacity 0.1s ease-in;
overflow: visible !important;
/*
* The menu is portalled to `document.body`. A Radix modal dialog sets
* `pointer-events: none` on `body` while open and restores `auto` only on its
* own content element, so a menu opened from inside a dialog would render but
* ignore every click. `pointer-events` inherits, so re-enabling it here covers
* the whole menu subtree. Harmless outside a dialog.
*/
pointer-events: auto;
}

.positioner[data-closed] {
Expand Down
17 changes: 17 additions & 0 deletions src/code-components/DialogV2/DialogV2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ export function DialogV2({
event.preventDefault();
}}
onPointerDownOutside={(event) => {
if (isHeadlessUiPortalClick(event)) {
event.preventDefault();
return;
}
preventEventIfScrollbarClick(event);
onPointerDownOutside?.(event);
}}
Expand All @@ -74,6 +78,19 @@ export function DialogV2({
);
}

/**
* A Headless UI menu (Combobox, Listbox, Menu) opened from inside the dialog is
* portalled to `document.body`, so Radix sees a click on one of its options as a
* click outside the dialog and closes it mid-selection. Treat those clicks as
* inside.
*/
function isHeadlessUiPortalClick(event: PointerDownOutsideEvent) {
const target = event.target;
return (
target instanceof Element && !!target.closest("[data-headlessui-portal]")
);
}

/**
* Based on https://github.com/tailwindlabs/headlessui/pull/1333/files#diff-d095a5f3fa3ad7f5ff99576cb61e5d75a979a6b7d5557f8a092f5d5c8c0c34deR49
*/
Expand Down
Loading