Fix filter multi select (#8682)
- Created a dropdown inside a dropdown for the `ObjectFilterDropdownOperandDropdown` so the operand can be opened over the selection with an offset - Refactored dropdown component and introduced `DropdownUnmountEffect` to close the dropdown when the component unmounts - Removed old logic Before: <img width="216" alt="Capture d’écran 2024-11-22 à 14 03 58" src="https://github.com/user-attachments/assets/3c1bba03-af03-4993-a070-f009b8dc876f"> After: <img width="222" alt="Capture d’écran 2024-11-22 à 14 03 40" src="https://github.com/user-attachments/assets/a8a784b4-8672-4b02-bb21-e4a749682f2e">
This commit is contained in:
@ -21,6 +21,7 @@ import { isDefined } from '~/utils/isDefined';
|
||||
import { useDropdown } from '../hooks/useDropdown';
|
||||
import { useInternalHotkeyScopeManagement } from '../hooks/useInternalHotkeyScopeManagement';
|
||||
|
||||
import { DropdownUnmountEffect } from '@/ui/layout/dropdown/components/DropdownUnmountEffect';
|
||||
import { useListenClickOutsideV2 } from '@/ui/utilities/pointer-event/hooks/useListenClickOutsideV2';
|
||||
import { DropdownMenu } from './DropdownMenu';
|
||||
import { DropdownOnToggleEffect } from './DropdownOnToggleEffect';
|
||||
@ -149,25 +150,38 @@ export const Dropdown = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<DropdownScope dropdownScopeId={getScopeIdFromComponentId(dropdownId)}>
|
||||
<div ref={containerRef} className={className}>
|
||||
{clickableComponent && (
|
||||
<div
|
||||
ref={refs.setReference}
|
||||
onClick={handleClickableComponentClick}
|
||||
className={className}
|
||||
>
|
||||
{clickableComponent}
|
||||
</div>
|
||||
)}
|
||||
{hotkey && (
|
||||
<HotkeyEffect
|
||||
hotkey={hotkey}
|
||||
onHotkeyTriggered={handleHotkeyTriggered}
|
||||
/>
|
||||
)}
|
||||
{isDropdownOpen && usePortal && (
|
||||
<FloatingPortal>
|
||||
<>
|
||||
<DropdownScope dropdownScopeId={getScopeIdFromComponentId(dropdownId)}>
|
||||
<div ref={containerRef} className={className}>
|
||||
{clickableComponent && (
|
||||
<div
|
||||
ref={refs.setReference}
|
||||
onClick={handleClickableComponentClick}
|
||||
className={className}
|
||||
>
|
||||
{clickableComponent}
|
||||
</div>
|
||||
)}
|
||||
{hotkey && (
|
||||
<HotkeyEffect
|
||||
hotkey={hotkey}
|
||||
onHotkeyTriggered={handleHotkeyTriggered}
|
||||
/>
|
||||
)}
|
||||
{isDropdownOpen && usePortal && (
|
||||
<FloatingPortal>
|
||||
<DropdownMenu
|
||||
disableBlur={disableBlur}
|
||||
width={dropdownMenuWidth ?? dropdownWidth}
|
||||
data-select-disable
|
||||
ref={refs.setFloating}
|
||||
style={floatingStyles}
|
||||
>
|
||||
{dropdownComponents}
|
||||
</DropdownMenu>
|
||||
</FloatingPortal>
|
||||
)}
|
||||
{isDropdownOpen && !usePortal && (
|
||||
<DropdownMenu
|
||||
disableBlur={disableBlur}
|
||||
width={dropdownMenuWidth ?? dropdownWidth}
|
||||
@ -177,24 +191,14 @@ export const Dropdown = ({
|
||||
>
|
||||
{dropdownComponents}
|
||||
</DropdownMenu>
|
||||
</FloatingPortal>
|
||||
)}
|
||||
{isDropdownOpen && !usePortal && (
|
||||
<DropdownMenu
|
||||
disableBlur={disableBlur}
|
||||
width={dropdownMenuWidth ?? dropdownWidth}
|
||||
data-select-disable
|
||||
ref={refs.setFloating}
|
||||
style={floatingStyles}
|
||||
>
|
||||
{dropdownComponents}
|
||||
</DropdownMenu>
|
||||
)}
|
||||
<DropdownOnToggleEffect
|
||||
onDropdownClose={onClose}
|
||||
onDropdownOpen={onOpen}
|
||||
/>
|
||||
</div>
|
||||
</DropdownScope>
|
||||
)}
|
||||
<DropdownOnToggleEffect
|
||||
onDropdownClose={onClose}
|
||||
onDropdownOpen={onOpen}
|
||||
/>
|
||||
</div>
|
||||
</DropdownScope>
|
||||
<DropdownUnmountEffect dropdownId={dropdownId} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@ -49,6 +49,7 @@ type DropdownMenuHeaderProps = ComponentProps<'li'> & {
|
||||
EndIcon?: IconComponent;
|
||||
onClick?: (event: MouseEvent<HTMLButtonElement>) => void;
|
||||
testId?: string;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export const DropdownMenuHeader = ({
|
||||
@ -57,12 +58,17 @@ export const DropdownMenuHeader = ({
|
||||
EndIcon,
|
||||
onClick,
|
||||
testId,
|
||||
className,
|
||||
}: DropdownMenuHeaderProps) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<>
|
||||
{EndIcon && (
|
||||
<StyledHeader data-testid={testId} onClick={onClick}>
|
||||
<StyledHeader
|
||||
data-testid={testId}
|
||||
onClick={onClick}
|
||||
className={className}
|
||||
>
|
||||
<StyledChildrenWrapper>{children}</StyledChildrenWrapper>
|
||||
<StyledEndIcon>
|
||||
<EndIcon size={theme.icon.size.md} />
|
||||
@ -70,7 +76,7 @@ export const DropdownMenuHeader = ({
|
||||
</StyledHeader>
|
||||
)}
|
||||
{StartIcon && (
|
||||
<StyledHeader data-testid={testId}>
|
||||
<StyledHeader data-testid={testId} className={className}>
|
||||
<LightIconButton
|
||||
testId="dropdown-menu-header-end-icon"
|
||||
Icon={StartIcon}
|
||||
|
||||
@ -37,12 +37,17 @@ const StyledDropdownMenuItemsInternalContainer = styled.div`
|
||||
export const DropdownMenuItemsContainer = ({
|
||||
children,
|
||||
hasMaxHeight,
|
||||
className,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
hasMaxHeight?: boolean;
|
||||
className?: string;
|
||||
}) => {
|
||||
return (
|
||||
<StyledDropdownMenuItemsExternalContainer hasMaxHeight={hasMaxHeight}>
|
||||
<StyledDropdownMenuItemsExternalContainer
|
||||
hasMaxHeight={hasMaxHeight}
|
||||
className={className}
|
||||
>
|
||||
{hasMaxHeight ? (
|
||||
<StyledScrollWrapper contextProviderName="dropdownMenuItemsContainer">
|
||||
<StyledDropdownMenuItemsInternalContainer>
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
import { useDropdownV2 } from '@/ui/layout/dropdown/hooks/useDropdownV2';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
export const DropdownUnmountEffect = ({
|
||||
dropdownId,
|
||||
}: {
|
||||
dropdownId: string;
|
||||
}) => {
|
||||
const { closeDropdown } = useDropdownV2();
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
closeDropdown(dropdownId);
|
||||
};
|
||||
}, [closeDropdown, dropdownId]);
|
||||
|
||||
return null;
|
||||
};
|
||||
Reference in New Issue
Block a user