Fixed dropdown flip and resize edge cases (#12234)

This PR fixes the dropdown resize problems we had with some edge cases,
the most common was that when opening a dropdown that is placed near the
bottom end of the screen the dropdown would shrink to a ridiculously
small height instead of flipping.

With this PR we implement a mechanism that respects all of the existing
behaviors while fixing this edge case, and most of all allows for the
incoming refactor on harmonization of dropdown content width.

Before : 



https://github.com/user-attachments/assets/6da3b291-e60c-4353-94fb-45fef55ee0e1

After : 



https://github.com/user-attachments/assets/c9fd9a34-f5de-4701-a301-08cba1eafdad

Fixes https://github.com/twentyhq/core-team-issues/issues/980
This commit is contained in:
Lucas Bordeau
2025-05-23 11:07:47 +02:00
committed by GitHub
parent 710c859f4e
commit 75e4a5d19b
3 changed files with 29 additions and 14 deletions

View File

@ -1,5 +1,7 @@
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent'; import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownOnToggleEffect } from '@/ui/layout/dropdown/components/DropdownOnToggleEffect'; import { DropdownOnToggleEffect } from '@/ui/layout/dropdown/components/DropdownOnToggleEffect';
import { DROPDOWN_RESIZE_MIN_HEIGHT } from '@/ui/layout/dropdown/constants/DropdownResizeMinHeight';
import { DROPDOWN_RESIZE_MIN_WIDTH } from '@/ui/layout/dropdown/constants/DropdownResizeMinWidth';
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponeInstanceContext'; import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponeInstanceContext';
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope'; import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
import { dropdownHotkeyComponentState } from '@/ui/layout/dropdown/states/dropdownHotkeyComponentState'; import { dropdownHotkeyComponentState } from '@/ui/layout/dropdown/states/dropdownHotkeyComponentState';
@ -100,29 +102,40 @@ export const Dropdown = ({
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const bottomAutoresizePadding = isMobile ? 64 : 32; const bottomAutoresizePadding = isMobile ? 64 : 32;
const boundaryOptions = {
boundary: document.querySelector('#root') ?? undefined,
padding: {
right: 32,
left: 32,
bottom: bottomAutoresizePadding,
},
};
const { refs, floatingStyles, placement } = useFloating({ const { refs, floatingStyles, placement } = useFloating({
placement: dropdownPlacement, placement: dropdownPlacement,
middleware: [ middleware: [
...offsetMiddleware, ...offsetMiddleware,
flip(), flip({
...boundaryOptions,
}),
size({ size({
padding: {
right: 32,
bottom: bottomAutoresizePadding,
},
/**
* DO NOT TOUCH THIS apply() MIDDLEWARE PLEASE
* THIS IS MANDATORY FOR KEEPING AUTORESIZING FOR ALL DROPDOWNS
* IT'S THE STANDARD WAY OF WORKING RECOMMENDED BY THE LIBRARY
* See https://floating-ui.com/docs/size#usage
*/
apply: ({ availableHeight, availableWidth }) => { apply: ({ availableHeight, availableWidth }) => {
flushSync(() => { flushSync(() => {
setDropdownMaxHeight(availableHeight); const maxHeightToApply =
setDropdownMaxWidth(availableWidth); availableHeight < DROPDOWN_RESIZE_MIN_HEIGHT
? DROPDOWN_RESIZE_MIN_HEIGHT
: availableHeight;
const maxWidthToApply =
availableWidth < DROPDOWN_RESIZE_MIN_WIDTH
? DROPDOWN_RESIZE_MIN_WIDTH
: availableWidth;
setDropdownMaxHeight(maxHeightToApply);
setDropdownMaxWidth(maxWidthToApply);
}); });
}, },
boundary: document.querySelector('#root') ?? undefined, ...boundaryOptions,
}), }),
], ],
whileElementsMounted: autoUpdate, whileElementsMounted: autoUpdate,

View File

@ -0,0 +1 @@
export const DROPDOWN_RESIZE_MIN_HEIGHT = 200;

View File

@ -0,0 +1 @@
export const DROPDOWN_RESIZE_MIN_WIDTH = 140;