Use data attributes for click outside instead of classNames (#12228)

We previously used classnames to exclude elements from the click outside
listener.

With this PR we can now use `data-click-outside-id` instead of
`classNames` to target the elements we want to exclude from the click
outside listener.

We can also add `data-globally-prevent-click-outside` to a component to
globally prevent triggering click outside listeners for other
components. This attribute is especially useful for confirmation modals
and snackbar items.

Fixes #11785:


https://github.com/user-attachments/assets/318baa7e-0f82-4e3a-a447-bf981328462d
This commit is contained in:
Raphaël Bosi
2025-05-22 18:10:51 +02:00
committed by GitHub
parent 45c89a46d6
commit 051f0fc83f
28 changed files with 104 additions and 63 deletions
@@ -79,7 +79,6 @@ export const DropdownContent = ({
useListenClickOutside({
refs: [floatingUiRefs.floating, floatingUiRefs.domReference],
listenerId: dropdownId,
excludeClassNames: ['confirmation-modal'],
callback: (event) => {
if (activeDropdownFocusId !== dropdownId) return;
@@ -118,7 +117,7 @@ export const DropdownContent = ({
maxWidth: dropdownMaxWidth,
};
const { excludeClassName } = useContext(ClickOutsideListenerContext);
const { excludedClickOutsideId } = useContext(ClickOutsideListenerContext);
return (
<>
@@ -127,24 +126,23 @@ export const DropdownContent = ({
)}
<FloatingPortal>
<div className={excludeClassName}>
<StyledDropdownContentContainer
ref={floatingUiRefs.setFloating}
style={dropdownMenuStyles}
role="listbox"
id={`${dropdownId}-options`}
>
<OverlayContainer>
<DropdownMenu
id={dropdownId}
width={dropdownWidth}
data-select-disable
>
{dropdownComponents}
</DropdownMenu>
</OverlayContainer>
</StyledDropdownContentContainer>
</div>
<StyledDropdownContentContainer
ref={floatingUiRefs.setFloating}
style={dropdownMenuStyles}
role="listbox"
id={`${dropdownId}-options`}
data-click-outside-id={excludedClickOutsideId}
>
<OverlayContainer>
<DropdownMenu
id={dropdownId}
width={dropdownWidth}
data-select-disable
>
{dropdownComponents}
</DropdownMenu>
</OverlayContainer>
</StyledDropdownContentContainer>
</FloatingPortal>
</>
);