Fix broken dropdown auto resize behavior (#11423)
This PR was originally about fixing advanced filter dropdown auto resize to avoid breaking the app main container, but the regression is not limited to advanced filter dropdown, so this PR fixes the regression for every dropdown in the app. This PR adds a max dropdown max width to allow resizing dropdowns horizontally also, which can happen easily for the advanced filter dropdown. In this PR we also start removing `fieldMetadataItemUsedInDropdown` in component `AdvancedFilterDropdownTextInput` because it has no impact outside of this component which is used only once. The autoresize behavior determines the right padding-bottom between mobile and PC. Mobile : <img width="604" alt="Capture d’écran 2025-04-07 à 16 03 12" src="https://github.com/user-attachments/assets/fbdd8020-1bfc-4e01-8a05-3a9f114cdd40" /> PC : <img width="757" alt="Capture d’écran 2025-04-07 à 16 03 30" src="https://github.com/user-attachments/assets/f80a5967-8f60-40bb-ae3c-fa9eb4c65707" /> Fixes https://github.com/twentyhq/core-team-issues/issues/725 Fixes https://github.com/twentyhq/twenty/issues/11409 --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -72,7 +72,7 @@ export const RecordIndexActionMenuDropdown = () => {
|
|||||||
scope: ActionMenuDropdownHotkeyScope.ActionMenuDropdown,
|
scope: ActionMenuDropdownHotkeyScope.ActionMenuDropdown,
|
||||||
}}
|
}}
|
||||||
data-select-disable
|
data-select-disable
|
||||||
dropdownMenuWidth={width}
|
dropdownWidth={width}
|
||||||
dropdownPlacement="bottom-start"
|
dropdownPlacement="bottom-start"
|
||||||
dropdownStrategy="absolute"
|
dropdownStrategy="absolute"
|
||||||
dropdownOffset={{
|
dropdownOffset={{
|
||||||
|
|||||||
@ -48,7 +48,7 @@ export const AttachmentDropdown = ({
|
|||||||
clickableComponent={
|
clickableComponent={
|
||||||
<LightIconButton Icon={IconDotsVertical} accent="tertiary" />
|
<LightIconButton Icon={IconDotsVertical} accent="tertiary" />
|
||||||
}
|
}
|
||||||
dropdownMenuWidth={160}
|
dropdownWidth={160}
|
||||||
dropdownComponents={
|
dropdownComponents={
|
||||||
<DropdownMenuItemsContainer>
|
<DropdownMenuItemsContainer>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
|||||||
@ -5,43 +5,30 @@ import { ObjectFilterDropdownSearchInput } from '@/object-record/object-filter-d
|
|||||||
import { ObjectFilterDropdownSourceSelect } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownSourceSelect';
|
import { ObjectFilterDropdownSourceSelect } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownSourceSelect';
|
||||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||||
|
|
||||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
|
||||||
import { AdvancedFilterDropdownDateInput } from '@/object-record/advanced-filter/components/AdvancedFilterDropdownDateInput';
|
import { AdvancedFilterDropdownDateInput } from '@/object-record/advanced-filter/components/AdvancedFilterDropdownDateInput';
|
||||||
import { ObjectFilterDropdownBooleanSelect } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownBooleanSelect';
|
import { ObjectFilterDropdownBooleanSelect } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownBooleanSelect';
|
||||||
import { ObjectFilterDropdownTextInput } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownTextInput';
|
import { ObjectFilterDropdownTextInput } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownTextInput';
|
||||||
import { DATE_FILTER_TYPES } from '@/object-record/object-filter-dropdown/constants/DateFilterTypes';
|
import { DATE_FILTER_TYPES } from '@/object-record/object-filter-dropdown/constants/DateFilterTypes';
|
||||||
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
|
||||||
import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/subFieldNameUsedInDropdownComponentState';
|
import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/subFieldNameUsedInDropdownComponentState';
|
||||||
import { isFilterOnActorSourceSubField } from '@/object-record/object-filter-dropdown/utils/isFilterOnActorSourceSubField';
|
import { isFilterOnActorSourceSubField } from '@/object-record/object-filter-dropdown/utils/isFilterOnActorSourceSubField';
|
||||||
|
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
|
||||||
|
|
||||||
type AdvancedFilterDropdownFilterInputProps = {
|
type AdvancedFilterDropdownFilterInputProps = {
|
||||||
filterDropdownId?: string;
|
filterDropdownId?: string;
|
||||||
recordFilterId?: string;
|
recordFilter: RecordFilter;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AdvancedFilterDropdownFilterInput = ({
|
export const AdvancedFilterDropdownFilterInput = ({
|
||||||
filterDropdownId,
|
filterDropdownId,
|
||||||
recordFilterId,
|
recordFilter,
|
||||||
}: AdvancedFilterDropdownFilterInputProps) => {
|
}: AdvancedFilterDropdownFilterInputProps) => {
|
||||||
const fieldMetadataItemUsedInDropdown = useRecoilComponentValueV2(
|
|
||||||
fieldMetadataItemUsedInDropdownComponentSelector,
|
|
||||||
filterDropdownId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const subFieldNameUsedInDropdown = useRecoilComponentValueV2(
|
const subFieldNameUsedInDropdown = useRecoilComponentValueV2(
|
||||||
subFieldNameUsedInDropdownComponentState,
|
subFieldNameUsedInDropdownComponentState,
|
||||||
filterDropdownId,
|
filterDropdownId,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!isDefined(fieldMetadataItemUsedInDropdown)) {
|
const filterType = recordFilter.type;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const filterType = getFilterTypeFromFieldType(
|
|
||||||
fieldMetadataItemUsedInDropdown.type,
|
|
||||||
);
|
|
||||||
|
|
||||||
const isActorSourceCompositeFilter = isFilterOnActorSourceSubField(
|
const isActorSourceCompositeFilter = isFilterOnActorSourceSubField(
|
||||||
subFieldNameUsedInDropdown,
|
subFieldNameUsedInDropdown,
|
||||||
@ -57,7 +44,7 @@ export const AdvancedFilterDropdownFilterInput = ({
|
|||||||
<>
|
<>
|
||||||
<ObjectFilterDropdownSearchInput />
|
<ObjectFilterDropdownSearchInput />
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<ObjectFilterDropdownRecordSelect recordFilterId={recordFilterId} />
|
<ObjectFilterDropdownRecordSelect recordFilterId={recordFilter.id} />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{filterType === 'ACTOR' &&
|
{filterType === 'ACTOR' &&
|
||||||
|
|||||||
@ -1,57 +1,36 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
|
||||||
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
|
||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
|
||||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
|
||||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
||||||
|
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||||
import { TextInputV2 } from '@/ui/input/components/TextInputV2';
|
import { TextInputV2 } from '@/ui/input/components/TextInputV2';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
|
||||||
import { v4 } from 'uuid';
|
|
||||||
|
|
||||||
export const AdvancedFilterDropdownTextInput = () => {
|
type AdvancedFilterDropdownTextInputProps = {
|
||||||
const selectedOperandInDropdown = useRecoilComponentValueV2(
|
recordFilter: RecordFilter;
|
||||||
selectedOperandInDropdownComponentState,
|
};
|
||||||
);
|
|
||||||
|
|
||||||
const fieldMetadataItemUsedInDropdown = useRecoilComponentValueV2(
|
|
||||||
fieldMetadataItemUsedInDropdownComponentSelector,
|
|
||||||
);
|
|
||||||
|
|
||||||
const selectedFilter = useRecoilComponentValueV2(
|
|
||||||
selectedFilterComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
|
export const AdvancedFilterDropdownTextInput = ({
|
||||||
|
recordFilter,
|
||||||
|
}: AdvancedFilterDropdownTextInputProps) => {
|
||||||
const { applyRecordFilter } = useApplyRecordFilter();
|
const { applyRecordFilter } = useApplyRecordFilter();
|
||||||
|
|
||||||
const [inputValue, setInputValue] = useState(
|
const [inputValue, setInputValue] = useState(() => recordFilter?.value || '');
|
||||||
() => selectedFilter?.value || '',
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleChange = (newValue: string) => {
|
const handleChange = (newValue: string) => {
|
||||||
if (!fieldMetadataItemUsedInDropdown || !selectedOperandInDropdown) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setInputValue(newValue);
|
setInputValue(newValue);
|
||||||
|
|
||||||
applyRecordFilter({
|
applyRecordFilter({
|
||||||
id: selectedFilter?.id ? selectedFilter.id : v4(),
|
id: recordFilter.id,
|
||||||
fieldMetadataId: fieldMetadataItemUsedInDropdown?.id ?? '',
|
fieldMetadataId: recordFilter?.fieldMetadataId ?? '',
|
||||||
value: newValue,
|
value: newValue,
|
||||||
operand: selectedOperandInDropdown,
|
operand: recordFilter.operand,
|
||||||
displayValue: newValue,
|
displayValue: newValue,
|
||||||
type: getFilterTypeFromFieldType(fieldMetadataItemUsedInDropdown.type),
|
type: recordFilter.type,
|
||||||
label: fieldMetadataItemUsedInDropdown.label,
|
label: recordFilter.label,
|
||||||
recordFilterGroupId: selectedFilter?.recordFilterGroupId,
|
recordFilterGroupId: recordFilter?.recordFilterGroupId,
|
||||||
positionInRecordFilterGroup: selectedFilter?.positionInRecordFilterGroup,
|
positionInRecordFilterGroup: recordFilter?.positionInRecordFilterGroup,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!selectedOperandInDropdown || !fieldMetadataItemUsedInDropdown) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TextInputV2
|
<TextInputV2
|
||||||
value={inputValue}
|
value={inputValue}
|
||||||
|
|||||||
@ -5,8 +5,10 @@ import { AdvancedFilterRecordFilterRow } from '@/object-record/advanced-filter/c
|
|||||||
import { useChildRecordFiltersAndRecordFilterGroups } from '@/object-record/advanced-filter/hooks/useChildRecordFiltersAndRecordFilterGroups';
|
import { useChildRecordFiltersAndRecordFilterGroups } from '@/object-record/advanced-filter/hooks/useChildRecordFiltersAndRecordFilterGroups';
|
||||||
import { rootLevelRecordFilterGroupComponentSelector } from '@/object-record/advanced-filter/states/rootLevelRecordFilterGroupComponentSelector';
|
import { rootLevelRecordFilterGroupComponentSelector } from '@/object-record/advanced-filter/states/rootLevelRecordFilterGroupComponentSelector';
|
||||||
import { isRecordFilterGroupChildARecordFilterGroup } from '@/object-record/advanced-filter/utils/isRecordFilterGroupChildARecordFilterGroup';
|
import { isRecordFilterGroupChildARecordFilterGroup } from '@/object-record/advanced-filter/utils/isRecordFilterGroupChildARecordFilterGroup';
|
||||||
|
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
import { id } from 'date-fns/locale';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
|
||||||
const StyledContainer = styled.div<{ isGrayBackground?: boolean }>`
|
const StyledContainer = styled.div<{ isGrayBackground?: boolean }>`
|
||||||
@ -16,7 +18,7 @@ const StyledContainer = styled.div<{ isGrayBackground?: boolean }>`
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: ${({ theme }) => theme.spacing(2)};
|
gap: ${({ theme }) => theme.spacing(2)};
|
||||||
padding: ${({ theme }) => theme.spacing(2)};
|
padding: ${({ theme }) => theme.spacing(2)};
|
||||||
overflow: hidden;
|
min-width: 650px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const AdvancedFilterRootRecordFilterGroup = () => {
|
export const AdvancedFilterRootRecordFilterGroup = () => {
|
||||||
@ -34,28 +36,32 @@ export const AdvancedFilterRootRecordFilterGroup = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledContainer>
|
<ScrollWrapper componentInstanceId={`scroll-wrapper-dropdown-menu-${id}`}>
|
||||||
{childRecordFiltersAndRecordFilterGroups.map(
|
<StyledContainer>
|
||||||
(recordFilterGroupChild, recordFilterGroupChildIndex) =>
|
{childRecordFiltersAndRecordFilterGroups.map(
|
||||||
isRecordFilterGroupChildARecordFilterGroup(recordFilterGroupChild) ? (
|
(recordFilterGroupChild, recordFilterGroupChildIndex) =>
|
||||||
<AdvancedFilterRecordFilterGroupRow
|
isRecordFilterGroupChildARecordFilterGroup(
|
||||||
key={recordFilterGroupChild.id}
|
recordFilterGroupChild,
|
||||||
parentRecordFilterGroup={rootRecordFilterGroup}
|
) ? (
|
||||||
recordFilterGroup={recordFilterGroupChild}
|
<AdvancedFilterRecordFilterGroupRow
|
||||||
recordFilterGroupIndex={recordFilterGroupChildIndex}
|
key={recordFilterGroupChild.id}
|
||||||
/>
|
parentRecordFilterGroup={rootRecordFilterGroup}
|
||||||
) : (
|
recordFilterGroup={recordFilterGroupChild}
|
||||||
<AdvancedFilterRecordFilterRow
|
recordFilterGroupIndex={recordFilterGroupChildIndex}
|
||||||
key={recordFilterGroupChild.id}
|
/>
|
||||||
recordFilterGroup={rootRecordFilterGroup}
|
) : (
|
||||||
recordFilter={recordFilterGroupChild}
|
<AdvancedFilterRecordFilterRow
|
||||||
recordFilterIndex={recordFilterGroupChildIndex}
|
key={recordFilterGroupChild.id}
|
||||||
/>
|
recordFilterGroup={rootRecordFilterGroup}
|
||||||
),
|
recordFilter={recordFilterGroupChild}
|
||||||
)}
|
recordFilterIndex={recordFilterGroupChildIndex}
|
||||||
<AdvancedFilterAddFilterRuleSelect
|
/>
|
||||||
recordFilterGroup={rootRecordFilterGroup}
|
),
|
||||||
/>
|
)}
|
||||||
</StyledContainer>
|
<AdvancedFilterAddFilterRuleSelect
|
||||||
|
recordFilterGroup={rootRecordFilterGroup}
|
||||||
|
/>
|
||||||
|
</StyledContainer>
|
||||||
|
</ScrollWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -45,11 +45,15 @@ export const AdvancedFilterValueInput = ({
|
|||||||
const operandHasNoInput =
|
const operandHasNoInput =
|
||||||
recordFilter && !configurableViewFilterOperands.has(recordFilter.operand);
|
recordFilter && !configurableViewFilterOperands.has(recordFilter.operand);
|
||||||
|
|
||||||
|
if (!isDefined(recordFilter)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const handleFilterValueDropdownClose = () => {
|
const handleFilterValueDropdownClose = () => {
|
||||||
setObjectFilterDropdownSearchInput('');
|
setObjectFilterDropdownSearchInput('');
|
||||||
};
|
};
|
||||||
|
|
||||||
const filterType = recordFilter?.type;
|
const filterType = recordFilter.type;
|
||||||
|
|
||||||
const dropdownContentOffset =
|
const dropdownContentOffset =
|
||||||
filterType === 'DATE' || filterType === 'DATE_TIME'
|
filterType === 'DATE' || filterType === 'DATE_TIME'
|
||||||
@ -67,7 +71,7 @@ export const AdvancedFilterValueInput = ({
|
|||||||
) : isDefined(filterType) &&
|
) : isDefined(filterType) &&
|
||||||
(TEXT_FILTER_TYPES.includes(filterType) ||
|
(TEXT_FILTER_TYPES.includes(filterType) ||
|
||||||
NUMBER_FILTER_TYPES.includes(filterType)) ? (
|
NUMBER_FILTER_TYPES.includes(filterType)) ? (
|
||||||
<AdvancedFilterDropdownTextInput />
|
<AdvancedFilterDropdownTextInput recordFilter={recordFilter} />
|
||||||
) : (
|
) : (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
dropdownId={dropdownId}
|
dropdownId={dropdownId}
|
||||||
@ -77,14 +81,12 @@ export const AdvancedFilterValueInput = ({
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
dropdownComponents={
|
dropdownComponents={
|
||||||
<AdvancedFilterDropdownFilterInput
|
<AdvancedFilterDropdownFilterInput recordFilter={recordFilter} />
|
||||||
recordFilterId={recordFilter.id}
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
dropdownHotkeyScope={{ scope: dropdownId }}
|
dropdownHotkeyScope={{ scope: dropdownId }}
|
||||||
dropdownOffset={dropdownContentOffset}
|
dropdownOffset={dropdownContentOffset}
|
||||||
dropdownPlacement="bottom-start"
|
dropdownPlacement="bottom-start"
|
||||||
dropdownMenuWidth={280}
|
dropdownWidth={280}
|
||||||
onClose={handleFilterValueDropdownClose}
|
onClose={handleFilterValueDropdownClose}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import { ObjectFilterOperandSelectAndInput } from '@/object-record/object-filter
|
|||||||
import { objectFilterDropdownFilterIsSelectedComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFilterIsSelectedComponentState';
|
import { objectFilterDropdownFilterIsSelectedComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFilterIsSelectedComponentState';
|
||||||
import { objectFilterDropdownIsSelectingCompositeFieldComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownIsSelectingCompositeFieldComponentState';
|
import { objectFilterDropdownIsSelectingCompositeFieldComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownIsSelectingCompositeFieldComponentState';
|
||||||
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2';
|
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2';
|
||||||
import { MultipleFiltersDropdownFilterOnFilterChangedEffect } from './MultipleFiltersDropdownFilterOnFilterChangedEffect';
|
|
||||||
import { ObjectFilterDropdownFilterSelect } from './ObjectFilterDropdownFilterSelect';
|
import { ObjectFilterDropdownFilterSelect } from './ObjectFilterDropdownFilterSelect';
|
||||||
|
|
||||||
type MultipleFiltersDropdownContentProps = {
|
type MultipleFiltersDropdownContentProps = {
|
||||||
@ -40,7 +39,6 @@ export const MultipleFiltersDropdownContent = ({
|
|||||||
) : (
|
) : (
|
||||||
<ObjectFilterDropdownFilterSelect isAdvancedFilterButtonVisible />
|
<ObjectFilterDropdownFilterSelect isAdvancedFilterButtonVisible />
|
||||||
)}
|
)}
|
||||||
<MultipleFiltersDropdownFilterOnFilterChangedEffect />
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,36 +0,0 @@
|
|||||||
import { useEffect } from 'react';
|
|
||||||
|
|
||||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
|
||||||
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
|
||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
|
||||||
|
|
||||||
export const MultipleFiltersDropdownFilterOnFilterChangedEffect = () => {
|
|
||||||
const { setDropdownWidth } = useDropdown();
|
|
||||||
|
|
||||||
const fieldMetadataItemUsedInDropdown = useRecoilComponentValueV2(
|
|
||||||
fieldMetadataItemUsedInDropdownComponentSelector,
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!isDefined(fieldMetadataItemUsedInDropdown)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const filterType = getFilterTypeFromFieldType(
|
|
||||||
fieldMetadataItemUsedInDropdown.type,
|
|
||||||
);
|
|
||||||
|
|
||||||
switch (filterType) {
|
|
||||||
case 'DATE':
|
|
||||||
case 'DATE_TIME':
|
|
||||||
setDropdownWidth(280);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
setDropdownWidth(200);
|
|
||||||
}
|
|
||||||
}, [fieldMetadataItemUsedInDropdown, setDropdownWidth]);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
@ -33,7 +33,7 @@ export const ObjectOptionsDropdown = ({
|
|||||||
<Dropdown
|
<Dropdown
|
||||||
dropdownId={OBJECT_OPTIONS_DROPDOWN_ID}
|
dropdownId={OBJECT_OPTIONS_DROPDOWN_ID}
|
||||||
dropdownHotkeyScope={{ scope: TableOptionsHotkeyScope.Dropdown }}
|
dropdownHotkeyScope={{ scope: TableOptionsHotkeyScope.Dropdown }}
|
||||||
dropdownMenuWidth={DROPDOWN_WIDTH}
|
dropdownWidth={DROPDOWN_WIDTH}
|
||||||
dropdownOffset={{ y: DROPDOWN_OFFSET_Y }}
|
dropdownOffset={{ y: DROPDOWN_OFFSET_Y }}
|
||||||
clickableComponent={
|
clickableComponent={
|
||||||
<StyledHeaderDropdownButton isUnfolded={isDropdownOpen}>
|
<StyledHeaderDropdownButton isUnfolded={isDropdownOpen}>
|
||||||
|
|||||||
@ -26,8 +26,6 @@ describe('useOptionsDropdown', () => {
|
|||||||
closeDropdown: mockCloseDropdown,
|
closeDropdown: mockCloseDropdown,
|
||||||
toggleDropdown: jest.fn(),
|
toggleDropdown: jest.fn(),
|
||||||
openDropdown: jest.fn(),
|
openDropdown: jest.fn(),
|
||||||
dropdownWidth: undefined,
|
|
||||||
setDropdownWidth: jest.fn(),
|
|
||||||
dropdownPlacement: null,
|
dropdownPlacement: null,
|
||||||
setDropdownPlacement: jest.fn(),
|
setDropdownPlacement: jest.fn(),
|
||||||
});
|
});
|
||||||
|
|||||||
@ -46,7 +46,7 @@ export const RecordBoardColumnHeaderAggregateDropdown = ({
|
|||||||
dropdownHotkeyScope={{
|
dropdownHotkeyScope={{
|
||||||
scope: RecordBoardColumnHotkeyScope.ColumnHeader,
|
scope: RecordBoardColumnHotkeyScope.ColumnHeader,
|
||||||
}}
|
}}
|
||||||
dropdownMenuWidth={DROPDOWN_WIDTH}
|
dropdownWidth={DROPDOWN_WIDTH}
|
||||||
dropdownOffset={{ y: DROPDOWN_OFFSET_Y }}
|
dropdownOffset={{ y: DROPDOWN_OFFSET_Y }}
|
||||||
clickableComponent={
|
clickableComponent={
|
||||||
<RecordBoardColumnHeaderAggregateDropdownButton
|
<RecordBoardColumnHeaderAggregateDropdownButton
|
||||||
|
|||||||
@ -78,7 +78,7 @@ export const RecordIndexAddRecordInGroupDropdown = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
dropdownMenuWidth="200px"
|
dropdownWidth="200px"
|
||||||
dropdownPlacement="bottom-start"
|
dropdownPlacement="bottom-start"
|
||||||
clickableComponent={clickableComponent}
|
clickableComponent={clickableComponent}
|
||||||
dropdownId={dropdownId}
|
dropdownId={dropdownId}
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
|
|||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||||
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
|
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
|
||||||
import { Trans, useLingui } from '@lingui/react/macro';
|
import { Trans, useLingui } from '@lingui/react/macro';
|
||||||
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
|
|
||||||
import {
|
import {
|
||||||
IconCalendarEvent,
|
IconCalendarEvent,
|
||||||
IconDotsVertical,
|
IconDotsVertical,
|
||||||
@ -20,6 +19,7 @@ import {
|
|||||||
} from 'twenty-ui/display';
|
} from 'twenty-ui/display';
|
||||||
import { LightIconButton } from 'twenty-ui/input';
|
import { LightIconButton } from 'twenty-ui/input';
|
||||||
import { MenuItem } from 'twenty-ui/navigation';
|
import { MenuItem } from 'twenty-ui/navigation';
|
||||||
|
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
|
||||||
|
|
||||||
type SettingsAccountsRowDropdownMenuProps = {
|
type SettingsAccountsRowDropdownMenuProps = {
|
||||||
account: ConnectedAccount;
|
account: ConnectedAccount;
|
||||||
@ -55,7 +55,7 @@ export const SettingsAccountsRowDropdownMenu = ({
|
|||||||
clickableComponent={
|
clickableComponent={
|
||||||
<LightIconButton Icon={IconDotsVertical} accent="tertiary" />
|
<LightIconButton Icon={IconDotsVertical} accent="tertiary" />
|
||||||
}
|
}
|
||||||
dropdownMenuWidth={160}
|
dropdownWidth={160}
|
||||||
dropdownComponents={
|
dropdownComponents={
|
||||||
<DropdownMenuItemsContainer>
|
<DropdownMenuItemsContainer>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
|||||||
@ -4,14 +4,14 @@ import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
|||||||
import { phonesSchema as phonesFieldDefaultValueSchema } from '@/object-record/record-field/types/guards/isFieldPhonesValue';
|
import { phonesSchema as phonesFieldDefaultValueSchema } from '@/object-record/record-field/types/guards/isFieldPhonesValue';
|
||||||
import { SettingsOptionCardContentSelect } from '@/settings/components/SettingsOptions/SettingsOptionCardContentSelect';
|
import { SettingsOptionCardContentSelect } from '@/settings/components/SettingsOptions/SettingsOptionCardContentSelect';
|
||||||
import { countryCodeToCallingCode } from '@/settings/data-model/fields/preview/utils/getPhonesFieldPreviewValue';
|
import { countryCodeToCallingCode } from '@/settings/data-model/fields/preview/utils/getPhonesFieldPreviewValue';
|
||||||
import { useCountries } from '@/ui/input/components/internal/hooks/useCountries';
|
|
||||||
import { Select } from '@/ui/input/components/Select';
|
import { Select } from '@/ui/input/components/Select';
|
||||||
|
import { useCountries } from '@/ui/input/components/internal/hooks/useCountries';
|
||||||
|
import { useLingui } from '@lingui/react/macro';
|
||||||
import { CountryCode } from 'libphonenumber-js';
|
import { CountryCode } from 'libphonenumber-js';
|
||||||
|
import { IconCircleOff, IconComponentProps, IconMap } from 'twenty-ui/display';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { applySimpleQuotesToString } from '~/utils/string/applySimpleQuotesToString';
|
import { applySimpleQuotesToString } from '~/utils/string/applySimpleQuotesToString';
|
||||||
import { stripSimpleQuotesFromString } from '~/utils/string/stripSimpleQuotesFromString';
|
import { stripSimpleQuotesFromString } from '~/utils/string/stripSimpleQuotesFromString';
|
||||||
import { useLingui } from '@lingui/react/macro';
|
|
||||||
import { IconCircleOff, IconComponentProps, IconMap } from 'twenty-ui/display';
|
|
||||||
|
|
||||||
type SettingsDataModelFieldPhonesFormProps = {
|
type SettingsDataModelFieldPhonesFormProps = {
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
@ -74,7 +74,6 @@ export const SettingsDataModelFieldPhonesForm = ({
|
|||||||
description={t`The default country code for new phone numbers.`}
|
description={t`The default country code for new phone numbers.`}
|
||||||
>
|
>
|
||||||
<Select<string>
|
<Select<string>
|
||||||
dropdownWidth={'auto'}
|
|
||||||
dropdownId="selectDefaultCountryCode"
|
dropdownId="selectDefaultCountryCode"
|
||||||
value={stripSimpleQuotesFromString(
|
value={stripSimpleQuotesFromString(
|
||||||
value?.primaryPhoneCountryCode,
|
value?.primaryPhoneCountryCode,
|
||||||
|
|||||||
@ -55,7 +55,7 @@ export const SettingsObjectFieldActiveActionDropdown = ({
|
|||||||
accent="tertiary"
|
accent="tertiary"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
dropdownMenuWidth={160}
|
dropdownWidth={160}
|
||||||
dropdownComponents={
|
dropdownComponents={
|
||||||
<DropdownMenuItemsContainer>
|
<DropdownMenuItemsContainer>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
|||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||||
import { t } from '@lingui/core/macro';
|
import { t } from '@lingui/core/macro';
|
||||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
|
||||||
import {
|
import {
|
||||||
IconArchiveOff,
|
IconArchiveOff,
|
||||||
IconDotsVertical,
|
IconDotsVertical,
|
||||||
@ -12,6 +11,7 @@ import {
|
|||||||
} from 'twenty-ui/display';
|
} from 'twenty-ui/display';
|
||||||
import { LightIconButton } from 'twenty-ui/input';
|
import { LightIconButton } from 'twenty-ui/input';
|
||||||
import { MenuItem } from 'twenty-ui/navigation';
|
import { MenuItem } from 'twenty-ui/navigation';
|
||||||
|
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||||
|
|
||||||
type SettingsObjectFieldInactiveActionDropdownProps = {
|
type SettingsObjectFieldInactiveActionDropdownProps = {
|
||||||
isCustomField?: boolean;
|
isCustomField?: boolean;
|
||||||
@ -60,7 +60,7 @@ export const SettingsObjectFieldInactiveActionDropdown = ({
|
|||||||
accent="tertiary"
|
accent="tertiary"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
dropdownMenuWidth={160}
|
dropdownWidth={160}
|
||||||
dropdownComponents={
|
dropdownComponents={
|
||||||
<DropdownMenuItemsContainer>
|
<DropdownMenuItemsContainer>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
|||||||
@ -77,7 +77,7 @@ export const SettingsObjectSummaryCard = ({
|
|||||||
accent="tertiary"
|
accent="tertiary"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
dropdownMenuWidth={160}
|
dropdownWidth={160}
|
||||||
dropdownComponents={
|
dropdownComponents={
|
||||||
<DropdownMenuItemsContainer>
|
<DropdownMenuItemsContainer>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
|||||||
@ -42,7 +42,7 @@ export const SettingsObjectInactiveMenuDropDown = ({
|
|||||||
accent="tertiary"
|
accent="tertiary"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
dropdownMenuWidth={160}
|
dropdownWidth={160}
|
||||||
dropdownComponents={
|
dropdownComponents={
|
||||||
<DropdownMenuItemsContainer>
|
<DropdownMenuItemsContainer>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
|||||||
@ -8,11 +8,11 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
|
|||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||||
import { useLingui } from '@lingui/react/macro';
|
import { useLingui } from '@lingui/react/macro';
|
||||||
import { UnwrapRecoilValue } from 'recoil';
|
import { UnwrapRecoilValue } from 'recoil';
|
||||||
import { SsoIdentityProviderStatus } from '~/generated/graphql';
|
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import { IconArchive, IconDotsVertical, IconTrash } from 'twenty-ui/display';
|
import { IconArchive, IconDotsVertical, IconTrash } from 'twenty-ui/display';
|
||||||
import { LightIconButton } from 'twenty-ui/input';
|
import { LightIconButton } from 'twenty-ui/input';
|
||||||
import { MenuItem } from 'twenty-ui/navigation';
|
import { MenuItem } from 'twenty-ui/navigation';
|
||||||
|
import { SsoIdentityProviderStatus } from '~/generated/graphql';
|
||||||
|
|
||||||
type SettingsSecuritySSORowDropdownMenuProps = {
|
type SettingsSecuritySSORowDropdownMenuProps = {
|
||||||
SSOIdp: UnwrapRecoilValue<typeof SSOIdentitiesProvidersState>[0];
|
SSOIdp: UnwrapRecoilValue<typeof SSOIdentitiesProvidersState>[0];
|
||||||
@ -72,7 +72,7 @@ export const SettingsSecuritySSORowDropdownMenu = ({
|
|||||||
clickableComponent={
|
clickableComponent={
|
||||||
<LightIconButton Icon={IconDotsVertical} accent="tertiary" />
|
<LightIconButton Icon={IconDotsVertical} accent="tertiary" />
|
||||||
}
|
}
|
||||||
dropdownMenuWidth={160}
|
dropdownWidth={160}
|
||||||
dropdownComponents={
|
dropdownComponents={
|
||||||
<DropdownMenuItemsContainer>
|
<DropdownMenuItemsContainer>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
|
import { approvedAccessDomainsState } from '@/settings/security/states/ApprovedAccessDomainsState';
|
||||||
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
|
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
|
||||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||||
import { UnwrapRecoilValue, useSetRecoilState } from 'recoil';
|
import { UnwrapRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
import { useDeleteApprovedAccessDomainMutation } from '~/generated/graphql';
|
|
||||||
import { approvedAccessDomainsState } from '@/settings/security/states/ApprovedAccessDomainsState';
|
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import { IconDotsVertical, IconTrash } from 'twenty-ui/display';
|
import { IconDotsVertical, IconTrash } from 'twenty-ui/display';
|
||||||
import { LightIconButton } from 'twenty-ui/input';
|
import { LightIconButton } from 'twenty-ui/input';
|
||||||
import { MenuItem } from 'twenty-ui/navigation';
|
import { MenuItem } from 'twenty-ui/navigation';
|
||||||
|
import { useDeleteApprovedAccessDomainMutation } from '~/generated/graphql';
|
||||||
|
|
||||||
type SettingsSecurityApprovedAccessDomainRowDropdownMenuProps = {
|
type SettingsSecurityApprovedAccessDomainRowDropdownMenuProps = {
|
||||||
approvedAccessDomain: UnwrapRecoilValue<typeof approvedAccessDomainsState>[0];
|
approvedAccessDomain: UnwrapRecoilValue<typeof approvedAccessDomainsState>[0];
|
||||||
@ -61,7 +61,7 @@ export const SettingsSecurityApprovedAccessDomainRowDropdownMenu = ({
|
|||||||
clickableComponent={
|
clickableComponent={
|
||||||
<LightIconButton Icon={IconDotsVertical} accent="tertiary" />
|
<LightIconButton Icon={IconDotsVertical} accent="tertiary" />
|
||||||
}
|
}
|
||||||
dropdownMenuWidth={160}
|
dropdownWidth={160}
|
||||||
dropdownComponents={
|
dropdownComponents={
|
||||||
<DropdownMenuItemsContainer>
|
<DropdownMenuItemsContainer>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
|||||||
@ -26,7 +26,7 @@ export const SupportDropdown = () => {
|
|||||||
dropdownPlacement="top-start"
|
dropdownPlacement="top-start"
|
||||||
dropdownOffset={{ x: 0, y: -28 }}
|
dropdownOffset={{ x: 0, y: -28 }}
|
||||||
clickableComponent={<SupportButton />}
|
clickableComponent={<SupportButton />}
|
||||||
dropdownMenuWidth={160}
|
dropdownWidth={160}
|
||||||
dropdownComponents={
|
dropdownComponents={
|
||||||
<DropdownMenuItemsContainer>
|
<DropdownMenuItemsContainer>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousH
|
|||||||
import { arrayToChunks } from '~/utils/array/arrayToChunks';
|
import { arrayToChunks } from '~/utils/array/arrayToChunks';
|
||||||
|
|
||||||
import { t } from '@lingui/core/macro';
|
import { t } from '@lingui/core/macro';
|
||||||
import { IconPickerHotkeyScope } from '../types/IconPickerHotkeyScope';
|
|
||||||
import { IconApps, IconComponent, useIcons } from 'twenty-ui/display';
|
import { IconApps, IconComponent, useIcons } from 'twenty-ui/display';
|
||||||
import {
|
import {
|
||||||
IconButton,
|
IconButton,
|
||||||
@ -22,6 +21,7 @@ import {
|
|||||||
IconButtonVariant,
|
IconButtonVariant,
|
||||||
LightIconButton,
|
LightIconButton,
|
||||||
} from 'twenty-ui/input';
|
} from 'twenty-ui/input';
|
||||||
|
import { IconPickerHotkeyScope } from '../types/IconPickerHotkeyScope';
|
||||||
|
|
||||||
export type IconPickerProps = {
|
export type IconPickerProps = {
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
@ -172,7 +172,7 @@ export const IconPicker = ({
|
|||||||
size={size}
|
size={size}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
dropdownMenuWidth={176}
|
dropdownWidth={176}
|
||||||
dropdownComponents={
|
dropdownComponents={
|
||||||
<SelectableList
|
<SelectableList
|
||||||
selectableListId="icon-list"
|
selectableListId="icon-list"
|
||||||
|
|||||||
@ -30,7 +30,7 @@ export type SelectProps<Value extends SelectValue> = {
|
|||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
selectSizeVariant?: SelectSizeVariant;
|
selectSizeVariant?: SelectSizeVariant;
|
||||||
dropdownId: string;
|
dropdownId: string;
|
||||||
dropdownWidth?: `${string}px` | 'auto' | number;
|
dropdownWidth?: number;
|
||||||
dropdownWidthAuto?: boolean;
|
dropdownWidthAuto?: boolean;
|
||||||
emptyOption?: SelectOption<Value>;
|
emptyOption?: SelectOption<Value>;
|
||||||
fullWidth?: boolean;
|
fullWidth?: boolean;
|
||||||
@ -128,7 +128,7 @@ export const Select = <Value extends SelectValue>({
|
|||||||
) : (
|
) : (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
dropdownId={dropdownId}
|
dropdownId={dropdownId}
|
||||||
dropdownMenuWidth={dropDownMenuWidth}
|
dropdownWidth={dropDownMenuWidth}
|
||||||
dropdownPlacement="bottom-start"
|
dropdownPlacement="bottom-start"
|
||||||
dropdownOffset={dropdownOffset}
|
dropdownOffset={dropdownOffset}
|
||||||
clickableComponent={
|
clickableComponent={
|
||||||
@ -152,7 +152,10 @@ export const Select = <Value extends SelectValue>({
|
|||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
)}
|
)}
|
||||||
{!!filteredOptions.length && (
|
{!!filteredOptions.length && (
|
||||||
<DropdownMenuItemsContainer hasMaxHeight>
|
<DropdownMenuItemsContainer
|
||||||
|
hasMaxHeight
|
||||||
|
width={dropDownMenuWidth}
|
||||||
|
>
|
||||||
{filteredOptions.map((option) => (
|
{filteredOptions.map((option) => (
|
||||||
<MenuItemSelect
|
<MenuItemSelect
|
||||||
key={`${option.value}-${option.label}`}
|
key={`${option.value}-${option.label}`}
|
||||||
|
|||||||
@ -30,6 +30,8 @@ export const MONTH_AND_YEAR_DROPDOWN_YEAR_SELECT_ID =
|
|||||||
'date-picker-month-and-year-dropdown-year-select';
|
'date-picker-month-and-year-dropdown-year-select';
|
||||||
|
|
||||||
const StyledContainer = styled.div<{ calendarDisabled?: boolean }>`
|
const StyledContainer = styled.div<{ calendarDisabled?: boolean }>`
|
||||||
|
width: 280px;
|
||||||
|
|
||||||
& .react-datepicker {
|
& .react-datepicker {
|
||||||
border-color: ${({ theme }) => theme.border.color.light};
|
border-color: ${({ theme }) => theme.border.color.light};
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
|||||||
@ -3,9 +3,12 @@ import { DropdownOnToggleEffect } from '@/ui/layout/dropdown/components/Dropdown
|
|||||||
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';
|
||||||
|
import { dropdownMaxHeightComponentState } from '@/ui/layout/dropdown/states/internal/dropdownMaxHeightComponentState';
|
||||||
|
import { dropdownMaxWidthComponentState } from '@/ui/layout/dropdown/states/internal/dropdownMaxWidthComponentState';
|
||||||
import { DropdownOffset } from '@/ui/layout/dropdown/types/DropdownOffset';
|
import { DropdownOffset } from '@/ui/layout/dropdown/types/DropdownOffset';
|
||||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||||
import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId';
|
import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId';
|
||||||
|
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import {
|
import {
|
||||||
Placement,
|
Placement,
|
||||||
@ -20,6 +23,7 @@ import { flushSync } from 'react-dom';
|
|||||||
import { Keys } from 'react-hotkeys-hook';
|
import { Keys } from 'react-hotkeys-hook';
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
import { useIsMobile } from 'twenty-ui/utilities';
|
||||||
import { useDropdown } from '../hooks/useDropdown';
|
import { useDropdown } from '../hooks/useDropdown';
|
||||||
|
|
||||||
const StyledDropdownFallbackAnchor = styled.div`
|
const StyledDropdownFallbackAnchor = styled.div`
|
||||||
@ -43,7 +47,7 @@ export type DropdownProps = {
|
|||||||
dropdownHotkeyScope: HotkeyScope;
|
dropdownHotkeyScope: HotkeyScope;
|
||||||
dropdownId: string;
|
dropdownId: string;
|
||||||
dropdownPlacement?: Placement;
|
dropdownPlacement?: Placement;
|
||||||
dropdownMenuWidth?: `${string}px` | `${number}%` | 'auto' | number;
|
dropdownWidth?: `${string}px` | `${number}%` | 'auto' | number;
|
||||||
dropdownOffset?: DropdownOffset;
|
dropdownOffset?: DropdownOffset;
|
||||||
dropdownStrategy?: 'fixed' | 'absolute';
|
dropdownStrategy?: 'fixed' | 'absolute';
|
||||||
onClickOutside?: () => void;
|
onClickOutside?: () => void;
|
||||||
@ -56,7 +60,7 @@ export const Dropdown = ({
|
|||||||
className,
|
className,
|
||||||
clickableComponent,
|
clickableComponent,
|
||||||
dropdownComponents,
|
dropdownComponents,
|
||||||
dropdownMenuWidth,
|
dropdownWidth,
|
||||||
hotkey,
|
hotkey,
|
||||||
dropdownId,
|
dropdownId,
|
||||||
dropdownHotkeyScope,
|
dropdownHotkeyScope,
|
||||||
@ -82,17 +86,39 @@ export const Dropdown = ({
|
|||||||
]
|
]
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
|
const setDropdownMaxHeight = useSetRecoilComponentStateV2(
|
||||||
|
dropdownMaxHeightComponentState,
|
||||||
|
dropdownId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const setDropdownMaxWidth = useSetRecoilComponentStateV2(
|
||||||
|
dropdownMaxWidthComponentState,
|
||||||
|
dropdownId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const isMobile = useIsMobile();
|
||||||
|
const bottomAutoresizePadding = isMobile ? 64 : 32;
|
||||||
|
|
||||||
const { refs, floatingStyles, placement } = useFloating({
|
const { refs, floatingStyles, placement } = useFloating({
|
||||||
placement: dropdownPlacement,
|
placement: dropdownPlacement,
|
||||||
middleware: [
|
middleware: [
|
||||||
...offsetMiddleware,
|
...offsetMiddleware,
|
||||||
flip(),
|
flip(),
|
||||||
size({
|
size({
|
||||||
padding: 32,
|
padding: {
|
||||||
apply: () => {
|
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 }) => {
|
||||||
flushSync(() => {
|
flushSync(() => {
|
||||||
// TODO: I think this is not needed anymore let's remove it if not used for a few weeks
|
setDropdownMaxHeight(availableHeight);
|
||||||
// setDropdownMaxHeight(availableHeight);
|
setDropdownMaxWidth(availableWidth);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
boundary: document.querySelector('#root') ?? undefined,
|
boundary: document.querySelector('#root') ?? undefined,
|
||||||
@ -144,7 +170,7 @@ export const Dropdown = ({
|
|||||||
<DropdownContent
|
<DropdownContent
|
||||||
className={className}
|
className={className}
|
||||||
floatingStyles={floatingStyles}
|
floatingStyles={floatingStyles}
|
||||||
dropdownMenuWidth={dropdownMenuWidth}
|
dropdownWidth={dropdownWidth}
|
||||||
dropdownComponents={dropdownComponents}
|
dropdownComponents={dropdownComponents}
|
||||||
dropdownId={dropdownId}
|
dropdownId={dropdownId}
|
||||||
dropdownPlacement={placement}
|
dropdownPlacement={placement}
|
||||||
|
|||||||
@ -3,7 +3,8 @@ import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
|
|||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||||
import { useInternalHotkeyScopeManagement } from '@/ui/layout/dropdown/hooks/useInternalHotkeyScopeManagement';
|
import { useInternalHotkeyScopeManagement } from '@/ui/layout/dropdown/hooks/useInternalHotkeyScopeManagement';
|
||||||
import { activeDropdownFocusIdState } from '@/ui/layout/dropdown/states/activeDropdownFocusIdState';
|
import { activeDropdownFocusIdState } from '@/ui/layout/dropdown/states/activeDropdownFocusIdState';
|
||||||
import { dropdownMaxHeightComponentStateV2 } from '@/ui/layout/dropdown/states/dropdownMaxHeightComponentStateV2';
|
import { dropdownMaxHeightComponentState } from '@/ui/layout/dropdown/states/internal/dropdownMaxHeightComponentState';
|
||||||
|
import { dropdownMaxWidthComponentState } from '@/ui/layout/dropdown/states/internal/dropdownMaxWidthComponentState';
|
||||||
import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContainer';
|
import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContainer';
|
||||||
import { HotkeyEffect } from '@/ui/utilities/hotkey/components/HotkeyEffect';
|
import { HotkeyEffect } from '@/ui/utilities/hotkey/components/HotkeyEffect';
|
||||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||||
@ -40,7 +41,7 @@ export type DropdownContentProps = {
|
|||||||
scope: string;
|
scope: string;
|
||||||
};
|
};
|
||||||
onHotkeyTriggered?: () => void;
|
onHotkeyTriggered?: () => void;
|
||||||
dropdownMenuWidth?: `${string}px` | `${number}%` | 'auto' | number;
|
dropdownWidth?: `${string}px` | `${number}%` | 'auto' | number;
|
||||||
dropdownComponents: React.ReactNode;
|
dropdownComponents: React.ReactNode;
|
||||||
parentDropdownId?: string;
|
parentDropdownId?: string;
|
||||||
avoidPortal?: boolean;
|
avoidPortal?: boolean;
|
||||||
@ -56,17 +57,22 @@ export const DropdownContent = ({
|
|||||||
floatingStyles,
|
floatingStyles,
|
||||||
hotkey,
|
hotkey,
|
||||||
onHotkeyTriggered,
|
onHotkeyTriggered,
|
||||||
dropdownMenuWidth,
|
dropdownWidth,
|
||||||
dropdownComponents,
|
dropdownComponents,
|
||||||
avoidPortal,
|
avoidPortal,
|
||||||
}: DropdownContentProps) => {
|
}: DropdownContentProps) => {
|
||||||
const { isDropdownOpen, closeDropdown, dropdownWidth, setDropdownPlacement } =
|
const { isDropdownOpen, closeDropdown, setDropdownPlacement } =
|
||||||
useDropdown(dropdownId);
|
useDropdown(dropdownId);
|
||||||
|
|
||||||
const activeDropdownFocusId = useRecoilValue(activeDropdownFocusIdState);
|
const activeDropdownFocusId = useRecoilValue(activeDropdownFocusIdState);
|
||||||
|
|
||||||
const dropdownMaxHeight = useRecoilComponentValueV2(
|
const dropdownMaxHeight = useRecoilComponentValueV2(
|
||||||
dropdownMaxHeightComponentStateV2,
|
dropdownMaxHeightComponentState,
|
||||||
|
dropdownId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const dropdownMaxWidth = useRecoilComponentValueV2(
|
||||||
|
dropdownMaxWidthComponentState,
|
||||||
dropdownId,
|
dropdownId,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -112,6 +118,7 @@ export const DropdownContent = ({
|
|||||||
const dropdownMenuStyles = {
|
const dropdownMenuStyles = {
|
||||||
...floatingStyles,
|
...floatingStyles,
|
||||||
maxHeight: dropdownMaxHeight,
|
maxHeight: dropdownMaxHeight,
|
||||||
|
maxWidth: dropdownMaxWidth,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -129,7 +136,7 @@ export const DropdownContent = ({
|
|||||||
<OverlayContainer>
|
<OverlayContainer>
|
||||||
<DropdownMenu
|
<DropdownMenu
|
||||||
className={className}
|
className={className}
|
||||||
width={dropdownMenuWidth ?? dropdownWidth}
|
width={dropdownWidth}
|
||||||
data-select-disable
|
data-select-disable
|
||||||
>
|
>
|
||||||
{dropdownComponents}
|
{dropdownComponents}
|
||||||
@ -148,7 +155,7 @@ export const DropdownContent = ({
|
|||||||
<DropdownMenu
|
<DropdownMenu
|
||||||
id={dropdownId}
|
id={dropdownId}
|
||||||
className={className}
|
className={className}
|
||||||
width={dropdownMenuWidth ?? dropdownWidth}
|
width={dropdownWidth}
|
||||||
data-select-disable
|
data-select-disable
|
||||||
>
|
>
|
||||||
{dropdownComponents}
|
{dropdownComponents}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
|
||||||
const StyledDropdownMenu = styled.div<{
|
const StyledDropdownMenu = styled.div<{
|
||||||
width?: `${string}px` | `${number}%` | 'auto' | number;
|
width?: `${string}px` | `${number}%` | 'auto' | number;
|
||||||
@ -7,8 +8,12 @@ const StyledDropdownMenu = styled.div<{
|
|||||||
|
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: ${({ width = 200 }) =>
|
width: ${({ width }) =>
|
||||||
typeof width === 'number' ? `${width}px` : width};
|
isDefined(width)
|
||||||
|
? typeof width === 'number'
|
||||||
|
? `${width}px`
|
||||||
|
: width
|
||||||
|
: 'auto'};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const DropdownMenu = StyledDropdownMenu;
|
export const DropdownMenu = StyledDropdownMenu;
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
||||||
|
import { css } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useId } from 'react';
|
import { useId } from 'react';
|
||||||
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
|
||||||
const StyledDropdownMenuItemsExternalContainer = styled.div<{
|
const StyledDropdownMenuItemsExternalContainer = styled.div<{
|
||||||
hasMaxHeight?: boolean;
|
hasMaxHeight?: boolean;
|
||||||
|
width: number;
|
||||||
}>`
|
}>`
|
||||||
--padding: ${({ theme }) => theme.spacing(1)};
|
--padding: ${({ theme }) => theme.spacing(1)};
|
||||||
|
|
||||||
@ -15,7 +18,11 @@ const StyledDropdownMenuItemsExternalContainer = styled.div<{
|
|||||||
|
|
||||||
padding: var(--padding);
|
padding: var(--padding);
|
||||||
|
|
||||||
width: calc(100% - 2 * var(--padding));
|
${({ width }) =>
|
||||||
|
isDefined(width) &&
|
||||||
|
css`
|
||||||
|
width: ${width}px;
|
||||||
|
`}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledDropdownMenuItemsInternalContainer = styled.div`
|
const StyledDropdownMenuItemsInternalContainer = styled.div`
|
||||||
@ -38,12 +45,14 @@ export const DropdownMenuItemsContainer = ({
|
|||||||
children,
|
children,
|
||||||
hasMaxHeight,
|
hasMaxHeight,
|
||||||
className,
|
className,
|
||||||
|
width = 200,
|
||||||
scrollable = true,
|
scrollable = true,
|
||||||
}: {
|
}: {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
hasMaxHeight?: boolean;
|
hasMaxHeight?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
scrollable?: boolean;
|
scrollable?: boolean;
|
||||||
|
width?: number;
|
||||||
}) => {
|
}) => {
|
||||||
const id = useId();
|
const id = useId();
|
||||||
|
|
||||||
@ -52,6 +61,7 @@ export const DropdownMenuItemsContainer = ({
|
|||||||
hasMaxHeight={hasMaxHeight}
|
hasMaxHeight={hasMaxHeight}
|
||||||
className={className}
|
className={className}
|
||||||
role="listbox"
|
role="listbox"
|
||||||
|
width={width}
|
||||||
>
|
>
|
||||||
{hasMaxHeight ? (
|
{hasMaxHeight ? (
|
||||||
<StyledScrollWrapper
|
<StyledScrollWrapper
|
||||||
@ -73,6 +83,7 @@ export const DropdownMenuItemsContainer = ({
|
|||||||
hasMaxHeight={hasMaxHeight}
|
hasMaxHeight={hasMaxHeight}
|
||||||
className={className}
|
className={className}
|
||||||
role="listbox"
|
role="listbox"
|
||||||
|
width={width}
|
||||||
>
|
>
|
||||||
<StyledDropdownMenuItemsInternalContainer>
|
<StyledDropdownMenuItemsInternalContainer>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@ -51,18 +51,4 @@ describe('useDropdown', () => {
|
|||||||
|
|
||||||
expect(result.current.isDropdownOpen).toBe(false);
|
expect(result.current.isDropdownOpen).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should change dropdownWidth', async () => {
|
|
||||||
const { result } = renderHook(() => useDropdown(dropdownId), {
|
|
||||||
wrapper: Wrapper,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.current.dropdownWidth).toBe(200);
|
|
||||||
|
|
||||||
await act(async () => {
|
|
||||||
result.current.setDropdownWidth(220);
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.current.dropdownWidth).toEqual(220);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { DropdownScopeInternalContext } from '@/ui/layout/dropdown/scopes/scope-internal-context/DropdownScopeInternalContext';
|
import { DropdownScopeInternalContext } from '@/ui/layout/dropdown/scopes/scope-internal-context/DropdownScopeInternalContext';
|
||||||
import { dropdownHotkeyComponentState } from '@/ui/layout/dropdown/states/dropdownHotkeyComponentState';
|
import { dropdownHotkeyComponentState } from '@/ui/layout/dropdown/states/dropdownHotkeyComponentState';
|
||||||
import { dropdownPlacementComponentState } from '@/ui/layout/dropdown/states/dropdownPlacementComponentState';
|
import { dropdownPlacementComponentState } from '@/ui/layout/dropdown/states/dropdownPlacementComponentState';
|
||||||
import { dropdownWidthComponentState } from '@/ui/layout/dropdown/states/dropdownWidthComponentState';
|
|
||||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||||
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
||||||
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
|
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
|
||||||
@ -28,10 +27,6 @@ export const useDropdownStates = ({
|
|||||||
dropdownHotkeyComponentState,
|
dropdownHotkeyComponentState,
|
||||||
scopeId,
|
scopeId,
|
||||||
),
|
),
|
||||||
dropdownWidthState: extractComponentState(
|
|
||||||
dropdownWidthComponentState,
|
|
||||||
scopeId,
|
|
||||||
),
|
|
||||||
isDropdownOpenState: extractComponentState(
|
isDropdownOpenState: extractComponentState(
|
||||||
isDropdownOpenComponentState,
|
isDropdownOpenComponentState,
|
||||||
scopeId,
|
scopeId,
|
||||||
|
|||||||
@ -12,14 +12,10 @@ import { useCallback } from 'react';
|
|||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
|
||||||
export const useDropdown = (dropdownId?: string) => {
|
export const useDropdown = (dropdownId?: string) => {
|
||||||
const {
|
const { scopeId, isDropdownOpenState, dropdownPlacementState } =
|
||||||
scopeId,
|
useDropdownStates({
|
||||||
dropdownWidthState,
|
dropdownScopeId: getScopeIdOrUndefinedFromComponentId(dropdownId),
|
||||||
isDropdownOpenState,
|
});
|
||||||
dropdownPlacementState,
|
|
||||||
} = useDropdownStates({
|
|
||||||
dropdownScopeId: getScopeIdOrUndefinedFromComponentId(dropdownId),
|
|
||||||
});
|
|
||||||
|
|
||||||
const { setActiveDropdownFocusIdAndMemorizePrevious } =
|
const { setActiveDropdownFocusIdAndMemorizePrevious } =
|
||||||
useSetActiveDropdownFocusIdAndMemorizePrevious();
|
useSetActiveDropdownFocusIdAndMemorizePrevious();
|
||||||
@ -32,8 +28,6 @@ export const useDropdown = (dropdownId?: string) => {
|
|||||||
goBackToPreviousHotkeyScope,
|
goBackToPreviousHotkeyScope,
|
||||||
} = usePreviousHotkeyScope();
|
} = usePreviousHotkeyScope();
|
||||||
|
|
||||||
const [dropdownWidth, setDropdownWidth] = useRecoilState(dropdownWidthState);
|
|
||||||
|
|
||||||
const [dropdownPlacement, setDropdownPlacement] = useRecoilState(
|
const [dropdownPlacement, setDropdownPlacement] = useRecoilState(
|
||||||
dropdownPlacementState,
|
dropdownPlacementState,
|
||||||
);
|
);
|
||||||
@ -103,8 +97,6 @@ export const useDropdown = (dropdownId?: string) => {
|
|||||||
closeDropdown,
|
closeDropdown,
|
||||||
toggleDropdown,
|
toggleDropdown,
|
||||||
openDropdown,
|
openDropdown,
|
||||||
dropdownWidth,
|
|
||||||
setDropdownWidth,
|
|
||||||
dropdownPlacement,
|
dropdownPlacement,
|
||||||
setDropdownPlacement,
|
setDropdownPlacement,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
|
||||||
|
|
||||||
export const dropdownWidthComponentState = createComponentState<
|
|
||||||
number | undefined
|
|
||||||
>({
|
|
||||||
key: 'dropdownWidthComponentState',
|
|
||||||
defaultValue: 200,
|
|
||||||
});
|
|
||||||
@ -1,10 +1,10 @@
|
|||||||
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponeInstanceContext';
|
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponeInstanceContext';
|
||||||
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
||||||
|
|
||||||
export const dropdownMaxHeightComponentStateV2 = createComponentStateV2<
|
export const dropdownMaxHeightComponentState = createComponentStateV2<
|
||||||
number | undefined
|
number | undefined
|
||||||
>({
|
>({
|
||||||
key: 'dropdownMaxHeightComponentStateV2',
|
key: 'dropdownMaxHeightComponentState',
|
||||||
componentInstanceContext: DropdownComponentInstanceContext,
|
componentInstanceContext: DropdownComponentInstanceContext,
|
||||||
defaultValue: undefined,
|
defaultValue: undefined,
|
||||||
});
|
});
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponeInstanceContext';
|
||||||
|
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
||||||
|
|
||||||
|
export const dropdownMaxWidthComponentState = createComponentStateV2<
|
||||||
|
number | undefined
|
||||||
|
>({
|
||||||
|
key: 'dropdownMaxWidthComponentState',
|
||||||
|
componentInstanceContext: DropdownComponentInstanceContext,
|
||||||
|
defaultValue: undefined,
|
||||||
|
});
|
||||||
@ -24,7 +24,7 @@ export const AdvancedFilterDropdownButton = () => {
|
|||||||
dropdownHotkeyScope={{ scope: ADVANCED_FILTER_DROPDOWN_ID }}
|
dropdownHotkeyScope={{ scope: ADVANCED_FILTER_DROPDOWN_ID }}
|
||||||
dropdownOffset={{ y: 8, x: 0 }}
|
dropdownOffset={{ y: 8, x: 0 }}
|
||||||
dropdownPlacement="bottom-start"
|
dropdownPlacement="bottom-start"
|
||||||
dropdownMenuWidth={650}
|
dropdownWidth="100%"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -74,7 +74,6 @@ export const ViewPickerDropdown = () => {
|
|||||||
dropdownHotkeyScope={{ scope: ViewsHotkeyScope.ListDropdown }}
|
dropdownHotkeyScope={{ scope: ViewsHotkeyScope.ListDropdown }}
|
||||||
dropdownOffset={{ x: 0, y: 8 }}
|
dropdownOffset={{ x: 0, y: 8 }}
|
||||||
dropdownPlacement="bottom-start"
|
dropdownPlacement="bottom-start"
|
||||||
dropdownMenuWidth={200}
|
|
||||||
onClickOutside={handleClickOutside}
|
onClickOutside={handleClickOutside}
|
||||||
clickableComponent={
|
clickableComponent={
|
||||||
<StyledDropdownButtonContainer isUnfolded={isViewsListDropdownOpen}>
|
<StyledDropdownButtonContainer isUnfolded={isViewsListDropdownOpen}>
|
||||||
|
|||||||
@ -174,7 +174,7 @@ export const WorkflowEditTriggerDatabaseEventForm = ({
|
|||||||
<StyledLabel>Record Type</StyledLabel>
|
<StyledLabel>Record Type</StyledLabel>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
dropdownId="workflow-edit-trigger-record-type"
|
dropdownId="workflow-edit-trigger-record-type"
|
||||||
dropdownMenuWidth={300}
|
dropdownWidth={300}
|
||||||
dropdownPlacement="bottom-start"
|
dropdownPlacement="bottom-start"
|
||||||
clickableComponent={
|
clickableComponent={
|
||||||
<SelectControl
|
<SelectControl
|
||||||
|
|||||||
@ -92,7 +92,7 @@ export const WorkflowVariablesDropdown = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
dropdownMenuWidth={320}
|
dropdownWidth={320}
|
||||||
dropdownId={dropdownId}
|
dropdownId={dropdownId}
|
||||||
dropdownHotkeyScope={{
|
dropdownHotkeyScope={{
|
||||||
scope: dropdownId,
|
scope: dropdownId,
|
||||||
|
|||||||
Reference in New Issue
Block a user