Refactor and fixes dropdown bugs (#8807)

Fixes https://github.com/twentyhq/twenty/issues/8788
Fixes https://github.com/twentyhq/twenty/issues/8793
Fixes https://github.com/twentyhq/twenty/issues/8791
Fixes https://github.com/twentyhq/twenty/issues/8890
Fixes https://github.com/twentyhq/twenty/issues/8893

- [x] Also : 

Icon buttons under dropdown are visible without blur : 

![Capture d’écran du 2024-11-29
15-09-53](https://github.com/user-attachments/assets/f563333d-4e43-4ded-acc7-62e116004ed9)

- [x] Also : 

<img width="237" alt="image"
src="https://github.com/user-attachments/assets/e4c70936-beff-4481-89cb-0a32a36e0ee2">

- [x] Also : 

<img width="335" alt="image"
src="https://github.com/user-attachments/assets/5be60395-6baf-49eb-8d40-197add049e20">

- [x] Also : 

<img width="287" alt="image"
src="https://github.com/user-attachments/assets/a317561f-7986-4d70-a1c0-deee4f4e268a">

- Button create new without padding
- Container is expanding

- [x] Also : 

<img width="303" alt="image"
src="https://github.com/user-attachments/assets/09f8a27f-91db-4191-acdc-aaaeedaf6da5">

- [x] Also : 

<img width="133" alt="image"
src="https://github.com/user-attachments/assets/fe17b32e-f7a4-46c4-8040-239eaf8198e8">

Font is cut at bottom ?

- [x] Also : 

<img width="385" alt="image"
src="https://github.com/user-attachments/assets/7bab2092-2936-4112-a2ee-d32d6737e304">

The component should flip and not resize in this situation

- [x] Also : 

<img width="244" alt="image"
src="https://github.com/user-attachments/assets/5384f49a-71f9-4638-a60c-158cc8c83f81">

- [x] Also : 


![image](https://github.com/user-attachments/assets/9cd1f43a-df59-401e-9a41-bdb8e93ebe58)
This commit is contained in:
Lucas Bordeau
2024-12-06 15:27:48 +01:00
committed by GitHub
parent 14b7bcf262
commit a9cb20f317
87 changed files with 1201 additions and 1192 deletions

View File

@ -0,0 +1,128 @@
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { useInternalHotkeyScopeManagement } from '@/ui/layout/dropdown/hooks/useInternalHotkeyScopeManagement';
import { activeDropdownFocusIdState } from '@/ui/layout/dropdown/states/activeDropdownFocusIdState';
import { dropdownMaxHeightComponentStateV2 } from '@/ui/layout/dropdown/states/dropdownMaxHeightComponentStateV2';
import { HotkeyEffect } from '@/ui/utilities/hotkey/components/HotkeyEffect';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId';
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2';
import {
FloatingPortal,
Placement,
UseFloatingReturn,
} from '@floating-ui/react';
import { useEffect } from 'react';
import { Keys } from 'react-hotkeys-hook';
import { useRecoilValue } from 'recoil';
import { Key } from 'ts-key-enum';
export type DropdownContentProps = {
className?: string;
dropdownId: string;
dropdownPlacement: Placement;
floatingUiRefs: UseFloatingReturn['refs'];
onClickOutside?: () => void;
hotkeyScope: HotkeyScope;
floatingStyles: UseFloatingReturn['floatingStyles'];
hotkey?: {
key: Keys;
scope: string;
};
onHotkeyTriggered?: () => void;
disableBlur?: boolean;
dropdownMenuWidth?: `${string}px` | `${number}%` | 'auto' | number;
dropdownComponents: React.ReactNode;
parentDropdownId?: string;
};
export const DropdownContent = ({
className,
dropdownId,
dropdownPlacement,
floatingUiRefs,
onClickOutside,
hotkeyScope,
floatingStyles,
hotkey,
onHotkeyTriggered,
disableBlur,
dropdownMenuWidth,
dropdownComponents,
}: DropdownContentProps) => {
const { isDropdownOpen, closeDropdown, dropdownWidth, setDropdownPlacement } =
useDropdown(dropdownId);
const activeDropdownFocusId = useRecoilValue(activeDropdownFocusIdState);
const [dropdownMaxHeight] = useRecoilComponentStateV2(
dropdownMaxHeightComponentStateV2,
dropdownId,
);
useEffect(() => {
setDropdownPlacement(dropdownPlacement);
}, [dropdownPlacement, setDropdownPlacement]);
useListenClickOutside({
refs: [floatingUiRefs.floating, floatingUiRefs.domReference],
listenerId: dropdownId,
callback: (event) => {
if (activeDropdownFocusId !== dropdownId) return;
if (isDropdownOpen) {
event.stopImmediatePropagation();
event.preventDefault();
closeDropdown();
}
onClickOutside?.();
},
});
useInternalHotkeyScopeManagement({
dropdownScopeId: getScopeIdFromComponentId(dropdownId),
dropdownHotkeyScopeFromParent: hotkeyScope,
});
useScopedHotkeys(
[Key.Escape],
() => {
if (activeDropdownFocusId !== dropdownId) return;
if (isDropdownOpen) {
closeDropdown();
}
},
hotkeyScope?.scope,
[closeDropdown, isDropdownOpen],
);
const dropdownMenuStyles = {
...floatingStyles,
maxHeight: dropdownMaxHeight,
};
return (
<>
{hotkey && onHotkeyTriggered && (
<HotkeyEffect hotkey={hotkey} onHotkeyTriggered={onHotkeyTriggered} />
)}
<FloatingPortal>
<DropdownMenu
className={className}
disableBlur={disableBlur}
width={dropdownMenuWidth ?? dropdownWidth}
data-select-disable
ref={floatingUiRefs.setFloating}
style={dropdownMenuStyles}
>
{dropdownComponents}
</DropdownMenu>
</FloatingPortal>
</>
);
};