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 :  - [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 : 
This commit is contained in:
@ -168,7 +168,7 @@ export const Select = <Value extends SelectValue>({
|
||||
<DropdownMenuSeparator />
|
||||
)}
|
||||
{!!callToActionButton && (
|
||||
<DropdownMenuItemsContainer hasMaxHeight>
|
||||
<DropdownMenuItemsContainer hasMaxHeight withoutScrollWrapper>
|
||||
<MenuItem
|
||||
onClick={callToActionButton.onClick}
|
||||
LeftIcon={callToActionButton.Icon}
|
||||
|
||||
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -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} />
|
||||
|
||||
@ -32,7 +32,7 @@ export const CurrencyPickerDropdownSelect = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<DropdownMenu width="240px" disableBlur>
|
||||
<DropdownMenu disableBlur>
|
||||
<DropdownMenuSearchInput
|
||||
value={searchFilter}
|
||||
onChange={(event) => setSearchFilter(event.target.value)}
|
||||
|
||||
Reference in New Issue
Block a user