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

@ -168,7 +168,7 @@ export const Select = <Value extends SelectValue>({
<DropdownMenuSeparator />
)}
{!!callToActionButton && (
<DropdownMenuItemsContainer hasMaxHeight>
<DropdownMenuItemsContainer hasMaxHeight withoutScrollWrapper>
<MenuItem
onClick={callToActionButton.onClick}
LeftIcon={callToActionButton.Icon}

View File

@ -1,5 +1,3 @@
import styled from '@emotion/styled';
import { SelectOption } from '@/spreadsheet-import/types';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
@ -8,32 +6,15 @@ import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/Dropdow
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { useTheme } from '@emotion/react';
import {
ReferenceType,
autoUpdate,
flip,
offset,
size,
useFloating,
} from '@floating-ui/react';
import { useEffect, useMemo, useRef, useState } from 'react';
import { Key } from 'ts-key-enum';
import { MenuItemSelectTag, TagColor, isDefined } from 'twenty-ui';
const StyledRelationPickerContainer = styled.div`
left: -1px;
position: absolute;
top: -1px;
z-index: ${({ theme }) => theme.lastLayerZIndex};
`;
interface SelectInputProps {
onOptionSelected: (selectedOption: SelectOption) => void;
options: SelectOption[];
onCancel?: () => void;
defaultOption?: SelectOption;
parentRef?: ReferenceType | null | undefined;
onFilterChange?: (filteredOptions: SelectOption[]) => void;
onClear?: () => void;
clearLabel?: string;
@ -47,13 +28,11 @@ export const SelectInput = ({
options,
onCancel,
defaultOption,
parentRef,
onFilterChange,
hotkeyScope,
}: SelectInputProps) => {
const containerRef = useRef<HTMLDivElement>(null);
const theme = useTheme();
const [searchFilter, setSearchFilter] = useState('');
const [selectedOption, setSelectedOption] = useState<
SelectOption | undefined
@ -81,27 +60,12 @@ export const SelectInput = ({
onOptionSelected(option);
};
const { refs, floatingStyles } = useFloating({
elements: { reference: parentRef },
strategy: 'absolute',
middleware: [
offset(() => {
return parseInt(theme.spacing(2), 10);
}),
flip(),
size(),
],
whileElementsMounted: autoUpdate,
open: true,
placement: 'bottom-start',
});
useEffect(() => {
onFilterChange?.(optionsInDropDown);
}, [onFilterChange, optionsInDropDown]);
useListenClickOutside({
refs: [refs.floating],
refs: [containerRef],
callback: (event) => {
event.stopImmediatePropagation();
@ -113,6 +77,7 @@ export const SelectInput = ({
onCancel();
}
},
listenerId: 'select-input',
});
useScopedHotkeys(
@ -130,44 +95,39 @@ export const SelectInput = ({
);
return (
<StyledRelationPickerContainer
ref={refs.setFloating}
style={floatingStyles}
>
<DropdownMenu ref={containerRef} data-select-disable>
<DropdownMenuSearchInput
value={searchFilter}
onChange={(e) => setSearchFilter(e.target.value)}
autoFocus
/>
<DropdownMenuSeparator />
<DropdownMenuItemsContainer hasMaxHeight>
{onClear && clearLabel && (
<DropdownMenu ref={containerRef} data-select-disable>
<DropdownMenuSearchInput
value={searchFilter}
onChange={(e) => setSearchFilter(e.target.value)}
autoFocus
/>
<DropdownMenuSeparator />
<DropdownMenuItemsContainer hasMaxHeight>
{onClear && clearLabel && (
<MenuItemSelectTag
key={`No ${clearLabel}`}
selected={false}
text={`No ${clearLabel}`}
color="transparent"
variant="outline"
onClick={() => {
setSelectedOption(undefined);
onClear();
}}
/>
)}
{optionsInDropDown.map((option) => {
return (
<MenuItemSelectTag
key={`No ${clearLabel}`}
selected={false}
text={`No ${clearLabel}`}
color="transparent"
variant="outline"
onClick={() => {
setSelectedOption(undefined);
onClear();
}}
key={option.value}
selected={selectedOption?.value === option.value}
text={option.label}
color={option.color as TagColor}
onClick={() => handleOptionChange(option)}
/>
)}
{optionsInDropDown.map((option) => {
return (
<MenuItemSelectTag
key={option.value}
selected={selectedOption?.value === option.value}
text={option.label}
color={option.color as TagColor}
onClick={() => handleOptionChange(option)}
/>
);
})}
</DropdownMenuItemsContainer>
</DropdownMenu>
</StyledRelationPickerContainer>
);
})}
</DropdownMenuItemsContainer>
</DropdownMenu>
);
};

View File

@ -10,11 +10,7 @@ import { CurrencyPickerHotkeyScope } from '../types/CurrencyPickerHotkeyScope';
import { CurrencyPickerDropdownSelect } from './CurrencyPickerDropdownSelect';
type StyledDropdownButtonProps = {
isUnfolded: boolean;
};
const StyledDropdownButtonContainer = styled.div<StyledDropdownButtonProps>`
const StyledDropdownButtonContainer = styled.div`
align-items: center;
color: ${({ color }) => color ?? 'none'};
cursor: pointer;
@ -62,7 +58,7 @@ export const CurrencyPickerDropdownButton = ({
}) => {
const theme = useTheme();
const { isDropdownOpen, closeDropdown } = useDropdown(
const { closeDropdown } = useDropdown(
CurrencyPickerHotkeyScope.CurrencyPicker,
);
@ -77,11 +73,10 @@ export const CurrencyPickerDropdownButton = ({
return (
<Dropdown
dropdownMenuWidth={200}
dropdownId="currncy-picker-dropdown-id"
dropdownId="currency-picker-dropdown-id"
dropdownHotkeyScope={{ scope: CurrencyPickerHotkeyScope.CurrencyPicker }}
clickableComponent={
<StyledDropdownButtonContainer isUnfolded={isDropdownOpen}>
<StyledDropdownButtonContainer>
<StyledIconContainer>
{currencyCode}
<IconChevronDown size={theme.icon.size.sm} />

View File

@ -32,7 +32,7 @@ export const CurrencyPickerDropdownSelect = ({
);
return (
<DropdownMenu width="240px" disableBlur>
<DropdownMenu disableBlur>
<DropdownMenuSearchInput
value={searchFilter}
onChange={(event) => setSearchFilter(event.target.value)}