Migrate dropdown to scope map (#3338)

* Migrate dropdown to scope map

* Run lintr

* Move Dropdown Scope internally

* Fix

* Fix lint

---------

Co-authored-by: Thomas Trompette <thomast@twenty.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Thomas Trompette
2024-01-10 15:46:37 +01:00
committed by GitHub
parent fbf7496fab
commit 2713285a0f
47 changed files with 803 additions and 881 deletions

View File

@ -11,7 +11,6 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
@ -23,7 +22,7 @@ import { IconPickerHotkeyScope } from '../types/IconPickerHotkeyScope';
type IconPickerProps = {
disabled?: boolean;
dropdownScopeId?: string;
dropdownId?: string;
onChange: (params: { iconKey: string; Icon: IconComponent }) => void;
selectedIconKey?: string;
onClickOutside?: () => void;
@ -80,7 +79,7 @@ const IconPickerIcon = ({
export const IconPicker = ({
disabled,
dropdownScopeId = 'icon-picker',
dropdownId = 'icon-picker',
onChange,
selectedIconKey,
onClickOutside,
@ -95,7 +94,7 @@ export const IconPicker = ({
setHotkeyScopeAndMemorizePreviousScope,
} = usePreviousHotkeyScope();
const { closeDropdown } = useDropdown(dropdownScopeId);
const { closeDropdown } = useDropdown(dropdownId);
const { getIcons, getIcon } = useIcons();
const icons = getIcons();
@ -126,71 +125,70 @@ export const IconPicker = ({
);
return (
<DropdownScope dropdownScopeId={dropdownScopeId}>
<div className={className}>
<Dropdown
dropdownHotkeyScope={{ scope: IconPickerHotkeyScope.IconPicker }}
clickableComponent={
<IconButton
disabled={disabled}
Icon={selectedIconKey ? getIcon(selectedIconKey) : IconApps}
variant={variant}
/>
}
dropdownMenuWidth={176}
dropdownComponents={
<SelectableList
selectableListId="icon-list"
selectableItemIdMatrix={iconKeys2d}
hotkeyScope={IconPickerHotkeyScope.IconPicker}
onEnter={(iconKey) => {
onChange({ iconKey, Icon: getIcon(iconKey) });
closeDropdown();
}}
>
<DropdownMenu width={176}>
<DropdownMenuSearchInput
placeholder="Search icon"
autoFocus
onChange={(event) => setSearchString(event.target.value)}
/>
<DropdownMenuSeparator />
<div
onMouseEnter={() => {
setHotkeyScopeAndMemorizePreviousScope(
IconPickerHotkeyScope.IconPicker,
);
}}
onMouseLeave={goBackToPreviousHotkeyScope}
>
<DropdownMenuItemsContainer>
<StyledMenuIconItemsContainer>
{iconKeys.map((iconKey) => (
<IconPickerIcon
key={iconKey}
iconKey={iconKey}
onClick={() => {
onChange({ iconKey, Icon: getIcon(iconKey) });
closeDropdown();
}}
selectedIconKey={selectedIconKey}
Icon={getIcon(iconKey)}
/>
))}
</StyledMenuIconItemsContainer>
</DropdownMenuItemsContainer>
</div>
</DropdownMenu>
</SelectableList>
}
onClickOutside={onClickOutside}
onClose={() => {
onClose?.();
setSearchString('');
}}
onOpen={onOpen}
/>
</div>
</DropdownScope>
<div className={className}>
<Dropdown
dropdownId={dropdownId}
dropdownHotkeyScope={{ scope: IconPickerHotkeyScope.IconPicker }}
clickableComponent={
<IconButton
disabled={disabled}
Icon={selectedIconKey ? getIcon(selectedIconKey) : IconApps}
variant={variant}
/>
}
dropdownMenuWidth={176}
dropdownComponents={
<SelectableList
selectableListId="icon-list"
selectableItemIdMatrix={iconKeys2d}
hotkeyScope={IconPickerHotkeyScope.IconPicker}
onEnter={(iconKey) => {
onChange({ iconKey, Icon: getIcon(iconKey) });
closeDropdown();
}}
>
<DropdownMenu width={176}>
<DropdownMenuSearchInput
placeholder="Search icon"
autoFocus
onChange={(event) => setSearchString(event.target.value)}
/>
<DropdownMenuSeparator />
<div
onMouseEnter={() => {
setHotkeyScopeAndMemorizePreviousScope(
IconPickerHotkeyScope.IconPicker,
);
}}
onMouseLeave={goBackToPreviousHotkeyScope}
>
<DropdownMenuItemsContainer>
<StyledMenuIconItemsContainer>
{iconKeys.map((iconKey) => (
<IconPickerIcon
key={iconKey}
iconKey={iconKey}
onClick={() => {
onChange({ iconKey, Icon: getIcon(iconKey) });
closeDropdown();
}}
selectedIconKey={selectedIconKey}
Icon={getIcon(iconKey)}
/>
))}
</StyledMenuIconItemsContainer>
</DropdownMenuItemsContainer>
</div>
</DropdownMenu>
</SelectableList>
}
onClickOutside={onClickOutside}
onClose={() => {
onClose?.();
setSearchString('');
}}
onOpen={onOpen}
/>
</div>
);
};

View File

@ -6,7 +6,6 @@ import { IconComponent } from '@/ui/display/icon/types/IconComponent';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
import { SelectHotkeyScope } from '../types/SelectHotkeyScope';
@ -98,31 +97,30 @@ export const Select = <Value extends string | number | null>({
{selectControl}
</div>
) : (
<DropdownScope dropdownScopeId={dropdownScopeId}>
<div className={className}>
{!!label && <StyledLabel>{label}</StyledLabel>}
<Dropdown
dropdownMenuWidth={176}
dropdownPlacement="bottom-start"
clickableComponent={selectControl}
dropdownComponents={
<DropdownMenuItemsContainer>
{options.map((option) => (
<MenuItem
key={option.value}
LeftIcon={option.Icon}
text={option.label}
onClick={() => {
onChange?.(option.value);
closeDropdown();
}}
/>
))}
</DropdownMenuItemsContainer>
}
dropdownHotkeyScope={{ scope: SelectHotkeyScope.Select }}
/>
</div>
</DropdownScope>
<div className={className}>
{!!label && <StyledLabel>{label}</StyledLabel>}
<Dropdown
dropdownId="select"
dropdownMenuWidth={176}
dropdownPlacement="bottom-start"
clickableComponent={selectControl}
dropdownComponents={
<DropdownMenuItemsContainer>
{options.map((option) => (
<MenuItem
key={option.value}
LeftIcon={option.Icon}
text={option.label}
onClick={() => {
onChange?.(option.value);
closeDropdown();
}}
/>
))}
</DropdownMenuItemsContainer>
}
dropdownHotkeyScope={{ scope: SelectHotkeyScope.Select }}
/>
</div>
);
};

View File

@ -9,7 +9,6 @@ import { CountryCallingCode } from 'libphonenumber-js';
import { IconChevronDown, IconWorld } from '@/ui/display/icon';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
import { CountryPickerHotkeyScope } from '../types/CountryPickerHotkeyScope';
@ -119,27 +118,26 @@ export const CountryPickerDropdownButton = ({
}, [countries, value]);
return (
<DropdownScope dropdownScopeId="country-picker">
<Dropdown
dropdownHotkeyScope={{ scope: CountryPickerHotkeyScope.CountryPicker }}
clickableComponent={
<StyledDropdownButtonContainer isUnfolded={isDropdownOpen}>
<StyledIconContainer>
{selectedCountry ? <selectedCountry.Flag /> : <IconWorld />}
<IconChevronDown size={theme.icon.size.sm} />
</StyledIconContainer>
</StyledDropdownButtonContainer>
}
dropdownComponents={
<CountryPickerDropdownSelect
countries={countries}
selectedCountry={selectedCountry}
onChange={handleChange}
/>
}
dropdownPlacement="bottom-start"
dropdownOffset={{ x: 0, y: 4 }}
/>
</DropdownScope>
<Dropdown
dropdownId="country-picker-dropdown-id"
dropdownHotkeyScope={{ scope: CountryPickerHotkeyScope.CountryPicker }}
clickableComponent={
<StyledDropdownButtonContainer isUnfolded={isDropdownOpen}>
<StyledIconContainer>
{selectedCountry ? <selectedCountry.Flag /> : <IconWorld />}
<IconChevronDown size={theme.icon.size.sm} />
</StyledIconContainer>
</StyledDropdownButtonContainer>
}
dropdownComponents={
<CountryPickerDropdownSelect
countries={countries}
selectedCountry={selectedCountry}
onChange={handleChange}
/>
}
dropdownPlacement="bottom-start"
dropdownOffset={{ x: 0, y: 4 }}
/>
);
};