Harmonize filter and sort dropdown width (#12649)

This PR sets the same width for all dropdowns used in filter and sort
features.

We use GenericDropdownContentWidth. ExtraLarge (320px) as specified on
Figma :
https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=44490-81923&t=h6KWtlM5WUm4aujY-11

Fixes https://github.com/twentyhq/core-team-issues/issues/1004
This commit is contained in:
Lucas Bordeau
2025-06-17 10:26:31 +02:00
committed by GitHub
parent 0043665202
commit 18d154282e
13 changed files with 78 additions and 68 deletions

View File

@ -17,6 +17,7 @@ import { isExpectedSubFieldName } from '@/object-record/object-filter-dropdown/u
import { isFilterOnActorSourceSubField } from '@/object-record/object-filter-dropdown/utils/isFilterOnActorSourceSubField';
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { FieldMetadataType } from 'twenty-shared/types';
@ -53,7 +54,7 @@ export const AdvancedFilterDropdownFilterInput = ({
<ObjectFilterDropdownDateInput />
)}
{filterType === 'RELATION' && (
<DropdownContent>
<DropdownContent widthInPixels={GenericDropdownContentWidth.ExtraLarge}>
<ObjectFilterDropdownSearchInput />
<DropdownMenuSeparator />
<ObjectFilterDropdownRecordSelect recordFilterId={recordFilter.id} />
@ -66,7 +67,7 @@ export const AdvancedFilterDropdownFilterInput = ({
<ObjectFilterDropdownTextInput />
))}
{['SELECT', 'MULTI_SELECT'].includes(filterType) && (
<DropdownContent>
<DropdownContent widthInPixels={GenericDropdownContentWidth.ExtraLarge}>
<ObjectFilterDropdownSearchInput />
<DropdownMenuSeparator />
<ObjectFilterDropdownOptionSelect />

View File

@ -23,6 +23,7 @@ import { isCompositeFieldType } from '@/object-record/object-filter-dropdown/uti
import { useFilterableFieldMetadataItemsInRecordIndexContext } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItemsInRecordIndexContext';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuSectionLabel } from '@/ui/layout/dropdown/components/DropdownMenuSectionLabel';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
import { useLingui } from '@lingui/react/macro';
@ -140,7 +141,7 @@ export const AdvancedFilterFieldSelectMenu = ({
const { t } = useLingui();
return (
<DropdownContent>
<DropdownContent widthInPixels={GenericDropdownContentWidth.ExtraLarge}>
<AdvancedFilterFieldSelectSearchInput />
<SelectableList
hotkeyScope={advancedFilterFieldSelectDropdownId}

View File

@ -18,6 +18,7 @@ import { CompositeFieldSubFieldName } from '@/settings/data-model/types/Composit
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader';
import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
@ -110,7 +111,7 @@ export const AdvancedFilterSubFieldSelectMenu = ({
];
return (
<DropdownContent>
<DropdownContent widthInPixels={GenericDropdownContentWidth.ExtraLarge}>
<DropdownMenuHeader
StartComponent={
<DropdownMenuHeaderLeftComponent

View File

@ -7,6 +7,7 @@ import { SingleRecordPickerHotkeyScope } from '@/object-record/record-picker/sin
import { BooleanDisplay } from '@/ui/field/display/components/BooleanDisplay';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { IconCheck } from 'twenty-ui/display';
@ -52,7 +53,7 @@ export const ObjectFilterDropdownBooleanSelect = () => {
};
return (
<DropdownContent>
<DropdownContent widthInPixels={GenericDropdownContentWidth.ExtraLarge}>
<SelectableList
selectableListInstanceId="boolean-select"
selectableItemIdArray={options.map((option) => option.toString())}

View File

@ -9,6 +9,7 @@ import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { useLingui } from '@lingui/react/macro';
import { isNonEmptyString } from '@sniptt/guards';
@ -96,7 +97,7 @@ export const ObjectFilterDropdownCountrySelect = () => {
const { t } = useLingui();
return (
<DropdownContent>
<DropdownContent widthInPixels={GenericDropdownContentWidth.ExtraLarge}>
<DropdownMenuSearchInput
autoFocus
type="text"

View File

@ -96,7 +96,7 @@ export const ObjectFilterDropdownCurrencySelect = () => {
searchText !== '';
return (
<DropdownContent widthInPixels={GenericDropdownContentWidth.Large}>
<DropdownContent widthInPixels={GenericDropdownContentWidth.ExtraLarge}>
<DropdownMenuSearchInput
autoFocus
type="text"

View File

@ -20,6 +20,7 @@ import { TEXT_FILTER_TYPES } from '@/object-record/object-filter-dropdown/consta
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { isDefined } from 'twenty-shared/utils';
@ -81,7 +82,7 @@ export const ObjectFilterDropdownFilterInput = ({
if (isOnlyOperand) {
return (
<DropdownContent>
<DropdownContent widthInPixels={GenericDropdownContentWidth.ExtraLarge}>
<ObjectFilterDropdownFilterInputHeader />
<ObjectFilterDropdownInnerSelectOperandDropdown />
</DropdownContent>
@ -97,7 +98,7 @@ export const ObjectFilterDropdownFilterInput = ({
);
} else {
return (
<DropdownContent>
<DropdownContent widthInPixels={GenericDropdownContentWidth.ExtraLarge}>
<ObjectFilterDropdownFilterInputHeader />
<ObjectFilterDropdownInnerSelectOperandDropdown />
<DropdownMenuSeparator />

View File

@ -5,6 +5,7 @@ import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
@ -46,7 +47,7 @@ export const ObjectFilterDropdownOperandSelect = () => {
};
return (
<DropdownContent>
<DropdownContent widthInPixels={GenericDropdownContentWidth.ExtraLarge}>
<StyledDropdownMenuItemsContainer>
{operandsForFilterType.map((filterOperand, index) => (
<MenuItem

View File

@ -6,6 +6,8 @@ import { getActorSourceMultiSelectOptions } from '@/object-record/object-filter-
import { SingleRecordPickerHotkeyScope } from '@/object-record/record-picker/single-record-picker/types/SingleRecordPickerHotkeyScope';
import { MultipleSelectDropdown } from '@/object-record/select/components/MultipleSelectDropdown';
import { SelectableItem } from '@/object-record/select/types/SelectableItem';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { isNonEmptyString } from '@sniptt/guards';
import { isDefined } from 'twenty-shared/utils';
@ -73,18 +75,20 @@ export const ObjectFilterDropdownSourceSelect = () => {
};
return (
<MultipleSelectDropdown
selectableListId="object-filter-source-select-id"
hotkeyScope={SingleRecordPickerHotkeyScope.SingleRecordPicker}
itemsToSelect={sourceTypes.filter(
(item) =>
!filteredSelectedItems.some((selected) => selected.id === item.id),
)}
filteredSelectedItems={filteredSelectedItems}
selectedItems={filteredSelectedItems}
onChange={handleMultipleItemSelectChange}
searchFilter={objectFilterDropdownSearchInput}
loadingItems={false}
/>
<DropdownContent widthInPixels={GenericDropdownContentWidth.ExtraLarge}>
<MultipleSelectDropdown
selectableListId="object-filter-source-select-id"
hotkeyScope={SingleRecordPickerHotkeyScope.SingleRecordPicker}
itemsToSelect={sourceTypes.filter(
(item) =>
!filteredSelectedItems.some((selected) => selected.id === item.id),
)}
filteredSelectedItems={filteredSelectedItems}
selectedItems={filteredSelectedItems}
onChange={handleMultipleItemSelectChange}
searchFilter={objectFilterDropdownSearchInput}
loadingItems={false}
/>
</DropdownContent>
);
};

View File

@ -25,6 +25,7 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
import { DropdownMenuSectionLabel } from '@/ui/layout/dropdown/components/DropdownMenuSectionLabel';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
@ -237,7 +238,7 @@ export const ObjectSortDropdownButton = ({
</StyledHeaderDropdownButton>
}
dropdownComponents={
<DropdownContent>
<DropdownContent widthInPixels={GenericDropdownContentWidth.ExtraLarge}>
<SelectableList
selectableListInstanceId={OBJECT_SORT_DROPDOWN_ID}
hotkeyScope={hotkeyScope.scope}

View File

@ -2,7 +2,6 @@ import { Key } from 'ts-key-enum';
import { SelectableItem } from '@/object-record/select/types/SelectableItem';
import { DropdownMenuSkeletonItem } from '@/ui/input/relation-picker/components/skeletons/DropdownMenuSkeletonItem';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
@ -81,48 +80,46 @@ export const MultipleSelectDropdown = ({
const selectableItemIds = itemsInDropdown.map((item) => item.id);
return (
<DropdownContent>
<SelectableList
selectableListInstanceId={selectableListId}
selectableItemIdArray={selectableItemIds}
hotkeyScope={hotkeyScope}
>
<DropdownMenuItemsContainer hasMaxHeight>
{itemsInDropdown?.map((item) => {
return (
<SelectableListItem
itemId={item.id}
onEnter={() => {
<SelectableList
selectableListInstanceId={selectableListId}
selectableItemIdArray={selectableItemIds}
hotkeyScope={hotkeyScope}
>
<DropdownMenuItemsContainer hasMaxHeight>
{itemsInDropdown?.map((item) => {
return (
<SelectableListItem
itemId={item.id}
onEnter={() => {
resetSelectedItem();
handleItemSelectChange(item, !item.isSelected);
}}
>
<MenuItemMultiSelectAvatar
key={item.id}
selected={item.isSelected}
isKeySelected={item.id === selectedItemId}
onSelectChange={(newCheckedValue) => {
resetSelectedItem();
handleItemSelectChange(item, !item.isSelected);
handleItemSelectChange(item, newCheckedValue);
}}
>
<MenuItemMultiSelectAvatar
key={item.id}
selected={item.isSelected}
isKeySelected={item.id === selectedItemId}
onSelectChange={(newCheckedValue) => {
resetSelectedItem();
handleItemSelectChange(item, newCheckedValue);
}}
text={item.name}
avatar={
<Avatar
avatarUrl={item.avatarUrl}
placeholderColorSeed={item.id}
placeholder={item.name}
size="md"
type={item.avatarType}
/>
}
/>
</SelectableListItem>
);
})}
{showNoResult && <MenuItem text="No results" />}
{loadingItems && <DropdownMenuSkeletonItem />}
</DropdownMenuItemsContainer>
</SelectableList>
</DropdownContent>
text={item.name}
avatar={
<Avatar
avatarUrl={item.avatarUrl}
placeholderColorSeed={item.id}
placeholder={item.name}
size="md"
type={item.avatarType}
/>
}
/>
</SelectableListItem>
);
})}
{showNoResult && <MenuItem text="No results" />}
{loadingItems && <DropdownMenuSkeletonItem />}
</DropdownMenuItemsContainer>
</SelectableList>
);
};

View File

@ -17,6 +17,7 @@ import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/
import { ViewBarFilterDropdownBottomMenu } from '@/views/components/ViewBarFilterDropdownBottomMenu';
import { ViewBarFilterDropdownFieldSelectMenuItem } from '@/views/components/ViewBarFilterDropdownFieldSelectMenuItem';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { VIEW_BAR_FILTER_BOTTOM_MENU_ITEM_IDS } from '@/views/constants/ViewBarFilterBottomMenuItemIds';
import { useLingui } from '@lingui/react/macro';
@ -81,7 +82,7 @@ export const ViewBarFilterDropdownFieldSelectMenu = () => {
const { t } = useLingui();
return (
<DropdownContent>
<DropdownContent widthInPixels={GenericDropdownContentWidth.ExtraLarge}>
<StyledInput
value={objectFilterDropdownSearchInput}
autoFocus

View File

@ -34,7 +34,7 @@ export const ViewBarFilterDropdownVectorSearchInput = ({
};
return (
<DropdownContent widthInPixels={GenericDropdownContentWidth.Medium}>
<DropdownContent widthInPixels={GenericDropdownContentWidth.ExtraLarge}>
<DropdownMenuSearchInput
autoFocus
type="text"