Removed useDropdown and its legacy states (#13111)

This PR removes useDropdown barrel hook and refactors the legacy
useDropdown states to the last version of our recoil component state
management.

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
This commit is contained in:
Lucas Bordeau
2025-07-08 20:16:15 +02:00
committed by GitHub
parent 1bf5139f03
commit 66b633e08e
33 changed files with 404 additions and 332 deletions

View File

@ -9,7 +9,7 @@ import { createMockActionMenuActions } from '@/action-menu/mock/action-menu-acti
import { ActionMenuComponentInstanceContext } from '@/action-menu/states/contexts/ActionMenuComponentInstanceContext'; import { ActionMenuComponentInstanceContext } from '@/action-menu/states/contexts/ActionMenuComponentInstanceContext';
import { recordIndexActionMenuDropdownPositionComponentState } from '@/action-menu/states/recordIndexActionMenuDropdownPositionComponentState'; import { recordIndexActionMenuDropdownPositionComponentState } from '@/action-menu/states/recordIndexActionMenuDropdownPositionComponentState';
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2'; import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState'; import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
import { import {
RouterDecorator, RouterDecorator,
@ -39,7 +39,7 @@ const meta: Meta<typeof RecordIndexActionMenuDropdown> = {
); );
set( set(
isDropdownOpenComponentStateV2.atomFamily({ isDropdownOpenComponentState.atomFamily({
instanceId: 'action-menu-dropdown-story-action-menu', instanceId: 'action-menu-dropdown-story-action-menu',
}), }),
true, true,

View File

@ -1,7 +1,7 @@
import { ObjectOptionsDropdownContextValue } from '@/object-record/object-options-dropdown/states/contexts/ObjectOptionsDropdownContext'; import { ObjectOptionsDropdownContextValue } from '@/object-record/object-options-dropdown/states/contexts/ObjectOptionsDropdownContext';
import { RecordBoardColumnHeaderAggregateDropdownContextValue } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownContext'; import { RecordBoardColumnHeaderAggregateDropdownContextValue } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownContext';
import { RecordTableColumnAggregateFooterDropdownContextValue } from '@/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterDropdownContext'; import { RecordTableColumnAggregateFooterDropdownContextValue } from '@/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterDropdownContext';
import { useDropdown as useDropdownUi } from '@/ui/layout/dropdown/hooks/useDropdown'; import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { Context, useCallback, useContext } from 'react'; import { Context, useCallback, useContext } from 'react';
/** /**
@ -28,12 +28,12 @@ export const useDropdownContextStateManagement = <
); );
} }
const dropdownId = dropdownContext.dropdownId; const dropdownId = dropdownContext.dropdownId;
const { closeDropdown } = useDropdownUi(dropdownId); const { closeDropdown } = useCloseDropdown();
const handleCloseDropdown = useCallback(() => { const handleCloseDropdown = useCallback(() => {
dropdownContext.resetContent(); dropdownContext.resetContent();
closeDropdown(); closeDropdown(dropdownId);
}, [closeDropdown, dropdownContext]); }, [closeDropdown, dropdownContext, dropdownId]);
return { return {
...dropdownContext, ...dropdownContext,

View File

@ -11,7 +11,7 @@ import { isLocationMatchingFavorite } from '@/favorites/utils/isLocationMatching
import { ProcessedFavorite } from '@/favorites/utils/sortFavorites'; import { ProcessedFavorite } from '@/favorites/utils/sortFavorites';
import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableItem'; import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableItem';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown'; import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2'; import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal'; import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
import { useModal } from '@/ui/layout/modal/hooks/useModal'; import { useModal } from '@/ui/layout/modal/hooks/useModal';
import { isModalOpenedComponentState } from '@/ui/layout/modal/states/isModalOpenedComponentState'; import { isModalOpenedComponentState } from '@/ui/layout/modal/states/isModalOpenedComponentState';
@ -74,7 +74,7 @@ export const CurrentWorkspaceMemberFavorites = ({
const dropdownId = `favorite-folder-edit-${folder.folderId}`; const dropdownId = `favorite-folder-edit-${folder.folderId}`;
const isDropdownOpenComponent = useRecoilComponentValueV2( const isDropdownOpenComponent = useRecoilComponentValueV2(
isDropdownOpenComponentStateV2, isDropdownOpenComponentState,
dropdownId, dropdownId,
); );

View File

@ -9,7 +9,7 @@ import { useRecordGroupReorderConfirmationModal } from '@/object-record/record-g
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton'; import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton';
import { DROPDOWN_OFFSET_Y } from '@/ui/layout/dropdown/constants/DropdownOffsetY'; import { DROPDOWN_OFFSET_Y } from '@/ui/layout/dropdown/constants/DropdownOffsetY';
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2'; import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { ViewType } from '@/views/types/ViewType'; import { ViewType } from '@/views/types/ViewType';
import { Trans } from '@lingui/react/macro'; import { Trans } from '@lingui/react/macro';
@ -29,7 +29,7 @@ export const ObjectOptionsDropdown = ({
useDropdownContextCurrentContentId<ObjectOptionsContentId>(); useDropdownContextCurrentContentId<ObjectOptionsContentId>();
const isDropdownOpen = useRecoilComponentValueV2( const isDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentStateV2, isDropdownOpenComponentState,
OBJECT_OPTIONS_DROPDOWN_ID, OBJECT_OPTIONS_DROPDOWN_ID,
); );

View File

@ -1,91 +0,0 @@
import { renderHook } from '@testing-library/react';
import { act } from 'react';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { OBJECT_OPTIONS_DROPDOWN_ID } from '@/object-record/object-options-dropdown/constants/ObjectOptionsDropdownId';
import { useObjectOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsDropdown';
import { ObjectOptionsDropdownContext } from '@/object-record/object-options-dropdown/states/contexts/ObjectOptionsDropdownContext';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { ViewType } from '@/views/types/ViewType';
jest.mock('@/ui/layout/dropdown/hooks/useDropdown', () => ({
useDropdown: jest.fn(() => ({
closeDropdown: jest.fn(),
})),
}));
describe('useOptionsDropdown', () => {
const mockOnContentChange = jest.fn();
const mockCloseDropdown = jest.fn();
const mockResetContent = jest.fn();
beforeEach(() => {
jest.mocked(useDropdown).mockReturnValue({
scopeId: 'mock-scope',
isDropdownOpen: false,
closeDropdown: mockCloseDropdown,
toggleDropdown: jest.fn(),
openDropdown: jest.fn(),
dropdownPlacement: null,
setDropdownPlacement: jest.fn(),
});
});
afterEach(() => {
jest.clearAllMocks();
});
const renderWithProvider = (contextValue: Partial<any> = {}) => {
const wrapper = ({ children }: any) => (
<ObjectOptionsDropdownContext.Provider
value={{
viewType: ViewType.Table,
objectMetadataItem: {
__typename: 'object',
id: '1',
nameSingular: 'company',
namePlural: 'companies',
labelSingular: 'Company',
labelPlural: 'Companies',
icon: 'IconBuildingSkyscraper',
fields: [{}],
} as ObjectMetadataItem,
recordIndexId: 'test-record-index',
currentContentId: 'recordGroups',
onContentChange: mockOnContentChange,
resetContent: mockResetContent,
dropdownId: OBJECT_OPTIONS_DROPDOWN_ID,
...contextValue,
}}
>
{children}
</ObjectOptionsDropdownContext.Provider>
);
return renderHook(() => useObjectOptionsDropdown(), { wrapper });
};
it('provides closeDropdown functionality from the context', () => {
const { result } = renderWithProvider();
act(() => {
result.current.closeDropdown();
});
expect(mockResetContent).toHaveBeenCalled();
expect(mockCloseDropdown).toHaveBeenCalled();
});
it('returns all context values', () => {
const { result } = renderWithProvider({
currentContentId: 'fields',
});
expect(result.current).toHaveProperty('currentContentId', 'fields');
expect(result.current).toHaveProperty(
'onContentChange',
mockOnContentChange,
);
expect(result.current).toHaveProperty('closeDropdown');
expect(result.current).toHaveProperty('resetContent', mockResetContent);
});
});

View File

@ -26,7 +26,7 @@ import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownM
import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton'; import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton';
import { DropdownHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownHotkeyScope'; import { DropdownHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownHotkeyScope';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth'; import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2'; import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList'; import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem'; import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState'; import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
@ -195,7 +195,7 @@ export const ObjectSortDropdownButton = () => {
}; };
const isDropdownOpen = useRecoilComponentValueV2( const isDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentStateV2, isDropdownOpenComponentState,
OBJECT_SORT_DROPDOWN_ID, OBJECT_SORT_DROPDOWN_ID,
); );

View File

@ -1,5 +1,5 @@
import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton'; import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton';
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2'; import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
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 { Tag } from 'twenty-ui/components'; import { Tag } from 'twenty-ui/components';
@ -23,7 +23,7 @@ export const RecordBoardColumnHeaderAggregateDropdownButton = ({
tooltip?: string; tooltip?: string;
}) => { }) => {
const isDropdownOpen = useRecoilComponentValueV2( const isDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentStateV2, isDropdownOpenComponentState,
dropdownId, dropdownId,
); );

View File

@ -1,7 +1,7 @@
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent'; import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown'; import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2'; import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { MenuItemWithOptionDropdown } from '@/ui/navigation/menu-item/components/MenuItemWithOptionDropdown'; import { MenuItemWithOptionDropdown } from '@/ui/navigation/menu-item/components/MenuItemWithOptionDropdown';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import React, { useState } from 'react'; import React, { useState } from 'react';
@ -37,7 +37,7 @@ export const MultiItemFieldMenuItem = <T,>({
const [isHovered, setIsHovered] = useState(false); const [isHovered, setIsHovered] = useState(false);
const { closeDropdown } = useCloseDropdown(); const { closeDropdown } = useCloseDropdown();
const isDropdownOpen = useRecoilComponentValueV2( const isDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentStateV2, isDropdownOpenComponentState,
dropdownId, dropdownId,
); );

View File

@ -36,7 +36,7 @@ import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown'; import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope'; import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2'; import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal'; import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
import { useModal } from '@/ui/layout/modal/hooks/useModal'; import { useModal } from '@/ui/layout/modal/hooks/useModal';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
@ -163,7 +163,7 @@ export const RecordDetailRelationRecordsListItem = ({
const { closeDropdown } = useCloseDropdown(); const { closeDropdown } = useCloseDropdown();
const isDropdownOpen = useRecoilComponentValueV2( const isDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentStateV2, isDropdownOpenComponentState,
dropdownScopeId, dropdownScopeId,
); );

View File

@ -16,7 +16,7 @@ import { AggregateOperations } from '@/object-record/record-table/constants/Aggr
import { ObjectRecord } from '@/object-record/types/ObjectRecord'; import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { prefetchIndexViewIdFromObjectMetadataItemFamilySelector } from '@/prefetch/states/selector/prefetchIndexViewIdFromObjectMetadataItemFamilySelector'; import { prefetchIndexViewIdFromObjectMetadataItemFamilySelector } from '@/prefetch/states/selector/prefetchIndexViewIdFromObjectMetadataItemFamilySelector';
import { AppPath } from '@/types/AppPath'; import { AppPath } from '@/types/AppPath';
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2'; import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand'; import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
@ -71,7 +71,7 @@ export const RecordDetailRelationSection = ({
}); });
const isDropdownOpen = useRecoilComponentValueV2( const isDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentStateV2, isDropdownOpenComponentState,
dropdownId, dropdownId,
); );

View File

@ -18,7 +18,7 @@ import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown'; import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope'; import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
import { dropdownPlacementComponentStateV2 } from '@/ui/layout/dropdown/states/dropdownPlacementComponentStateV2'; import { dropdownPlacementComponentState } from '@/ui/layout/dropdown/states/dropdownPlacementComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2'; import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
import { IconPlus } from 'twenty-ui/display'; import { IconPlus } from 'twenty-ui/display';
@ -55,7 +55,7 @@ export const RecordDetailRelationSectionDropdownToMany = () => {
const { closeDropdown } = useCloseDropdown(); const { closeDropdown } = useCloseDropdown();
const dropdownPlacement = useRecoilComponentValueV2( const dropdownPlacement = useRecoilComponentValueV2(
dropdownPlacementComponentStateV2, dropdownPlacementComponentState,
dropdownId, dropdownId,
); );

View File

@ -18,7 +18,7 @@ import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown'; import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope'; import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
import { dropdownPlacementComponentStateV2 } from '@/ui/layout/dropdown/states/dropdownPlacementComponentStateV2'; import { dropdownPlacementComponentState } from '@/ui/layout/dropdown/states/dropdownPlacementComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2'; import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
import { IconForbid, IconPencil } from 'twenty-ui/display'; import { IconForbid, IconPencil } from 'twenty-ui/display';
@ -57,7 +57,7 @@ export const RecordDetailRelationSectionDropdownToOne = () => {
const { closeDropdown } = useCloseDropdown(); const { closeDropdown } = useCloseDropdown();
const dropdownPlacement = useRecoilComponentValueV2( const dropdownPlacement = useRecoilComponentValueV2(
dropdownPlacementComponentStateV2, dropdownPlacementComponentState,
dropdownId, dropdownId,
); );

View File

@ -3,7 +3,7 @@ import { RECORD_TABLE_TD_WIDTH } from '@/object-record/record-table/record-table
import { RecordTableColumnAggregateFooterCellContext } from '@/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterCellContext'; import { RecordTableColumnAggregateFooterCellContext } from '@/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterCellContext';
import { RecordTableColumnAggregateFooterValue } from '@/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterValue'; import { RecordTableColumnAggregateFooterValue } from '@/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterValue';
import { hasAggregateOperationForViewFieldFamilySelector } from '@/object-record/record-table/record-table-footer/states/hasAggregateOperationForViewFieldFamilySelector'; import { hasAggregateOperationForViewFieldFamilySelector } from '@/object-record/record-table/record-table-footer/states/hasAggregateOperationForViewFieldFamilySelector';
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2'; import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
@ -62,7 +62,7 @@ export const RecordTableColumnAggregateFooterValueCell = ({
const [isHovered, setIsHovered] = useState(false); const [isHovered, setIsHovered] = useState(false);
const isDropdownOpen = useRecoilComponentValueV2( const isDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentStateV2, isDropdownOpenComponentState,
dropdownId, dropdownId,
); );

View File

@ -8,7 +8,7 @@ import { useEffect, useState } from 'react';
import { PhoneCountryPickerDropdownSelect } from './PhoneCountryPickerDropdownSelect'; import { PhoneCountryPickerDropdownSelect } from './PhoneCountryPickerDropdownSelect';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown'; import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2'; import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import 'react-phone-number-input/style.css'; import 'react-phone-number-input/style.css';
import { isDefined } from 'twenty-shared/utils'; import { isDefined } from 'twenty-shared/utils';
@ -80,7 +80,7 @@ export const PhoneCountryPickerDropdownButton = ({
const dropdownId = 'country-picker-dropdown-id'; const dropdownId = 'country-picker-dropdown-id';
const isDropdownOpen = useRecoilComponentValueV2( const isDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentStateV2, isDropdownOpenComponentState,
dropdownId, dropdownId,
); );

View File

@ -7,7 +7,7 @@ import { useToggleDropdown } from '@/ui/layout/dropdown/hooks/useToggleDropdown'
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope'; import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
import { dropdownMaxHeightComponentState } from '@/ui/layout/dropdown/states/internal/dropdownMaxHeightComponentState'; import { dropdownMaxHeightComponentState } from '@/ui/layout/dropdown/states/internal/dropdownMaxHeightComponentState';
import { dropdownMaxWidthComponentState } from '@/ui/layout/dropdown/states/internal/dropdownMaxWidthComponentState'; import { dropdownMaxWidthComponentState } from '@/ui/layout/dropdown/states/internal/dropdownMaxWidthComponentState';
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2'; import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { DropdownOffset } from '@/ui/layout/dropdown/types/DropdownOffset'; import { DropdownOffset } from '@/ui/layout/dropdown/types/DropdownOffset';
import { GlobalHotkeysConfig } from '@/ui/utilities/hotkey/types/GlobalHotkeysConfig'; import { GlobalHotkeysConfig } from '@/ui/utilities/hotkey/types/GlobalHotkeysConfig';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
@ -78,7 +78,7 @@ export const Dropdown = ({
isDropdownInModal = false, isDropdownInModal = false,
}: DropdownProps) => { }: DropdownProps) => {
const isDropdownOpen = useRecoilComponentValueV2( const isDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentStateV2, isDropdownOpenComponentState,
dropdownId, dropdownId,
); );

View File

@ -1,6 +1,7 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
export const DropdownOnToggleEffect = ({ export const DropdownOnToggleEffect = ({
onDropdownClose, onDropdownClose,
@ -9,7 +10,10 @@ export const DropdownOnToggleEffect = ({
onDropdownClose?: () => void; onDropdownClose?: () => void;
onDropdownOpen?: () => void; onDropdownOpen?: () => void;
}) => { }) => {
const { isDropdownOpen } = useDropdown(); const isDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentState,
);
const [currentIsDropdownOpen, setCurrentIsDropdownOpen] = const [currentIsDropdownOpen, setCurrentIsDropdownOpen] =
useState(isDropdownOpen); useState(isDropdownOpen);

View File

@ -1,10 +1,12 @@
import { RootStackingContextZIndices } from '@/ui/layout/constants/RootStackingContextZIndices'; import { RootStackingContextZIndices } from '@/ui/layout/constants/RootStackingContextZIndices';
import { DropdownHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownHotkeyScope'; import { DropdownHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownHotkeyScope';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { activeDropdownFocusIdState } from '@/ui/layout/dropdown/states/activeDropdownFocusIdState'; import { activeDropdownFocusIdState } from '@/ui/layout/dropdown/states/activeDropdownFocusIdState';
import { dropdownPlacementComponentStateV2 } from '@/ui/layout/dropdown/states/dropdownPlacementComponentStateV2'; import { dropdownPlacementComponentState } from '@/ui/layout/dropdown/states/dropdownPlacementComponentState';
import { dropdownMaxHeightComponentState } from '@/ui/layout/dropdown/states/internal/dropdownMaxHeightComponentState'; import { dropdownMaxHeightComponentState } from '@/ui/layout/dropdown/states/internal/dropdownMaxHeightComponentState';
import { dropdownMaxWidthComponentState } from '@/ui/layout/dropdown/states/internal/dropdownMaxWidthComponentState'; import { dropdownMaxWidthComponentState } from '@/ui/layout/dropdown/states/internal/dropdownMaxWidthComponentState';
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
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 { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement'; import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
@ -69,7 +71,11 @@ export const DropdownInternalContainer = ({
excludedClickOutsideIds, excludedClickOutsideIds,
isDropdownInModal = false, isDropdownInModal = false,
}: DropdownInternalContainerProps) => { }: DropdownInternalContainerProps) => {
const { isDropdownOpen, closeDropdown } = useDropdown(dropdownId); const isDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentState,
);
const { closeDropdown } = useCloseDropdown();
const activeDropdownFocusId = useRecoilValue(activeDropdownFocusIdState); const activeDropdownFocusId = useRecoilValue(activeDropdownFocusIdState);
@ -84,7 +90,7 @@ export const DropdownInternalContainer = ({
); );
const setDropdownPlacement = useSetRecoilComponentStateV2( const setDropdownPlacement = useSetRecoilComponentStateV2(
dropdownPlacementComponentStateV2, dropdownPlacementComponentState,
dropdownId, dropdownId,
); );
@ -103,7 +109,7 @@ export const DropdownInternalContainer = ({
event.stopImmediatePropagation(); event.stopImmediatePropagation();
event.preventDefault(); event.preventDefault();
closeDropdown(); closeDropdown(dropdownId);
} }
onClickOutside?.(); onClickOutside?.();
@ -117,7 +123,7 @@ export const DropdownInternalContainer = ({
if (activeDropdownFocusId !== dropdownId) return; if (activeDropdownFocusId !== dropdownId) return;
if (isDropdownOpen) { if (isDropdownOpen) {
closeDropdown(); closeDropdown(dropdownId);
} }
}, },
focusId: dropdownId, focusId: dropdownId,

View File

@ -6,7 +6,7 @@ import { RecoilRoot } from 'recoil';
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext'; import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
import { useCloseAnyOpenDropdown } from '@/ui/layout/dropdown/hooks/useCloseAnyOpenDropdown'; import { useCloseAnyOpenDropdown } from '@/ui/layout/dropdown/hooks/useCloseAnyOpenDropdown';
import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown'; import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2'; import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
const dropdownId = 'test-dropdown-id'; const dropdownId = 'test-dropdown-id';
@ -28,7 +28,7 @@ describe('useCloseAnyOpenDropdown', () => {
const { result } = renderHook( const { result } = renderHook(
() => { () => {
const isDropdownOpen = useRecoilComponentValueV2( const isDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentStateV2, isDropdownOpenComponentState,
dropdownId, dropdownId,
); );

View File

@ -0,0 +1,116 @@
import { expect } from '@storybook/test';
import { renderHook } from '@testing-library/react';
import { act } from 'react';
import { RecoilRoot } from 'recoil';
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
const dropdownId = 'test-dropdown-id';
const outsideDropdownId = 'test-dropdown-id-outside';
const Wrapper = ({ children }: { children: React.ReactNode }) => {
return (
<RecoilRoot>
<DropdownComponentInstanceContext.Provider
value={{ instanceId: dropdownId }}
>
{children}
</DropdownComponentInstanceContext.Provider>
<DropdownComponentInstanceContext.Provider
value={{ instanceId: outsideDropdownId }}
></DropdownComponentInstanceContext.Provider>
</RecoilRoot>
);
};
describe('useCloseDropdown', () => {
it('should close dropdown from inside component instance context', async () => {
const { result } = renderHook(
() => {
const isOutsideDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentState,
outsideDropdownId,
);
const isInsideDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentState,
);
const { closeDropdown } = useCloseDropdown();
const { openDropdown } = useOpenDropdown();
return {
isOutsideDropdownOpen,
isInsideDropdownOpen,
closeDropdown,
openDropdown,
};
},
{
wrapper: Wrapper,
},
);
act(() => {
result.current.openDropdown();
});
expect(result.current.isInsideDropdownOpen).toBe(true);
expect(result.current.isOutsideDropdownOpen).toBe(false);
act(() => {
result.current.closeDropdown();
});
expect(result.current.isInsideDropdownOpen).toBe(false);
expect(result.current.isOutsideDropdownOpen).toBe(false);
});
it('should close dropdown from outside component instance context', async () => {
const { result } = renderHook(
() => {
const isOutsideDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentState,
outsideDropdownId,
);
const isInsideDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentState,
);
const { closeDropdown } = useCloseDropdown();
const { openDropdown } = useOpenDropdown();
return {
isOutsideDropdownOpen,
isInsideDropdownOpen,
closeDropdown,
openDropdown,
};
},
{
wrapper: Wrapper,
},
);
act(() => {
result.current.openDropdown({
dropdownComponentInstanceIdFromProps: outsideDropdownId,
});
});
expect(result.current.isInsideDropdownOpen).toBe(false);
expect(result.current.isOutsideDropdownOpen).toBe(true);
act(() => {
result.current.closeDropdown(outsideDropdownId);
});
expect(result.current.isInsideDropdownOpen).toBe(false);
expect(result.current.isOutsideDropdownOpen).toBe(false);
});
});

View File

@ -1,54 +0,0 @@
import { expect } from '@storybook/test';
import { renderHook } from '@testing-library/react';
import { act } from 'react-dom/test-utils';
import { RecoilRoot } from 'recoil';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
const dropdownId = 'test-dropdown-id';
const Wrapper = ({ children }: { children: React.ReactNode }) => {
return <RecoilRoot>{children}</RecoilRoot>;
};
describe('useDropdown', () => {
it('should toggleDropdown', async () => {
const { result } = renderHook(() => useDropdown(dropdownId), {
wrapper: Wrapper,
});
expect(result.current.isDropdownOpen).toBe(false);
act(() => {
result.current.toggleDropdown();
});
expect(result.current.isDropdownOpen).toBe(true);
act(() => {
result.current.toggleDropdown();
});
expect(result.current.isDropdownOpen).toBe(false);
});
it('should open and close dropdown', async () => {
const { result } = renderHook(() => useDropdown(dropdownId), {
wrapper: Wrapper,
});
expect(result.current.isDropdownOpen).toBe(false);
act(() => {
result.current.openDropdown();
});
expect(result.current.isDropdownOpen).toBe(true);
act(() => {
result.current.closeDropdown();
});
expect(result.current.isDropdownOpen).toBe(false);
});
});

View File

@ -0,0 +1,95 @@
import { expect } from '@storybook/test';
import { renderHook } from '@testing-library/react';
import { act } from 'react';
import { RecoilRoot } from 'recoil';
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
const dropdownId = 'test-dropdown-id';
const outsideDropdownId = 'test-dropdown-id-outside';
const Wrapper = ({ children }: { children: React.ReactNode }) => {
return (
<RecoilRoot>
<DropdownComponentInstanceContext.Provider
value={{ instanceId: dropdownId }}
>
{children}
</DropdownComponentInstanceContext.Provider>
<DropdownComponentInstanceContext.Provider
value={{ instanceId: outsideDropdownId }}
></DropdownComponentInstanceContext.Provider>
</RecoilRoot>
);
};
describe('useOpenDropdown', () => {
it('should open dropdown from inside component instance context', async () => {
const { result } = renderHook(
() => {
const isOutsideDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentState,
outsideDropdownId,
);
const isInsideDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentState,
);
const { openDropdown } = useOpenDropdown();
return { isOutsideDropdownOpen, isInsideDropdownOpen, openDropdown };
},
{
wrapper: Wrapper,
},
);
expect(result.current.isInsideDropdownOpen).toBe(false);
expect(result.current.isOutsideDropdownOpen).toBe(false);
act(() => {
result.current.openDropdown();
});
expect(result.current.isInsideDropdownOpen).toBe(true);
expect(result.current.isOutsideDropdownOpen).toBe(false);
});
it('should open dropdown from outside component instance context', async () => {
const { result } = renderHook(
() => {
const isOutsideDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentState,
outsideDropdownId,
);
const isInsideDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentState,
);
const { openDropdown } = useOpenDropdown();
return { isInsideDropdownOpen, isOutsideDropdownOpen, openDropdown };
},
{
wrapper: Wrapper,
},
);
expect(result.current.isInsideDropdownOpen).toBe(false);
expect(result.current.isOutsideDropdownOpen).toBe(false);
act(() => {
result.current.openDropdown({
dropdownComponentInstanceIdFromProps: outsideDropdownId,
});
});
expect(result.current.isInsideDropdownOpen).toBe(false);
expect(result.current.isOutsideDropdownOpen).toBe(true);
});
});

View File

@ -0,0 +1,125 @@
import { expect } from '@storybook/test';
import { renderHook } from '@testing-library/react';
import { act } from 'react';
import { RecoilRoot } from 'recoil';
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
import { useToggleDropdown } from '@/ui/layout/dropdown/hooks/useToggleDropdown';
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
const dropdownId = 'test-dropdown-id';
const outsideDropdownId = 'test-dropdown-id-outside';
const Wrapper = ({ children }: { children: React.ReactNode }) => {
return (
<RecoilRoot>
<DropdownComponentInstanceContext.Provider
value={{ instanceId: dropdownId }}
>
{children}
</DropdownComponentInstanceContext.Provider>
<DropdownComponentInstanceContext.Provider
value={{ instanceId: outsideDropdownId }}
></DropdownComponentInstanceContext.Provider>
</RecoilRoot>
);
};
describe('useToggleDropdown', () => {
it('should toggle dropdown from inside component instance context', async () => {
const { result } = renderHook(
() => {
const isOutsideDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentState,
outsideDropdownId,
);
const isInsideDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentState,
);
const { toggleDropdown } = useToggleDropdown();
return { isOutsideDropdownOpen, isInsideDropdownOpen, toggleDropdown };
},
{
wrapper: Wrapper,
},
);
expect(result.current.isInsideDropdownOpen).toBe(false);
expect(result.current.isOutsideDropdownOpen).toBe(false);
act(() => {
result.current.toggleDropdown();
});
expect(result.current.isInsideDropdownOpen).toBe(true);
expect(result.current.isOutsideDropdownOpen).toBe(false);
act(() => {
result.current.toggleDropdown();
});
expect(result.current.isInsideDropdownOpen).toBe(false);
expect(result.current.isOutsideDropdownOpen).toBe(false);
act(() => {
result.current.toggleDropdown();
});
expect(result.current.isInsideDropdownOpen).toBe(true);
expect(result.current.isOutsideDropdownOpen).toBe(false);
});
it('should toggle dropdown from outside component instance context', async () => {
const { result } = renderHook(
() => {
const isOutsideDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentState,
outsideDropdownId,
);
const isInsideDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentState,
);
const { toggleDropdown } = useToggleDropdown();
return { isOutsideDropdownOpen, isInsideDropdownOpen, toggleDropdown };
},
{
wrapper: Wrapper,
},
);
expect(result.current.isInsideDropdownOpen).toBe(false);
expect(result.current.isOutsideDropdownOpen).toBe(false);
act(() => {
result.current.toggleDropdown({
dropdownComponentInstanceIdFromProps: outsideDropdownId,
});
});
expect(result.current.isInsideDropdownOpen).toBe(false);
expect(result.current.isOutsideDropdownOpen).toBe(true);
act(() => {
result.current.toggleDropdown({
dropdownComponentInstanceIdFromProps: outsideDropdownId,
});
});
expect(result.current.isInsideDropdownOpen).toBe(false);
expect(result.current.isOutsideDropdownOpen).toBe(false);
act(() => {
result.current.toggleDropdown({
dropdownComponentInstanceIdFromProps: outsideDropdownId,
});
});
expect(result.current.isInsideDropdownOpen).toBe(false);
expect(result.current.isOutsideDropdownOpen).toBe(true);
});
});

View File

@ -1,19 +0,0 @@
import { DropdownScopeInternalContext } from '@/ui/layout/dropdown/scopes/scope-internal-context/DropdownScopeInternalContext';
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
type UseDropdownStatesProps = {
dropdownScopeId?: string;
};
export const useDropdownStates = ({
dropdownScopeId,
}: UseDropdownStatesProps) => {
const scopeId = useAvailableScopeIdOrThrow(
DropdownScopeInternalContext,
dropdownScopeId,
);
return {
scopeId,
};
};

View File

@ -1,7 +1,7 @@
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext'; import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
import { useGoBackToPreviousDropdownFocusId } from '@/ui/layout/dropdown/hooks/useGoBackToPreviousDropdownFocusId'; import { useGoBackToPreviousDropdownFocusId } from '@/ui/layout/dropdown/hooks/useGoBackToPreviousDropdownFocusId';
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2';
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById'; import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
import { useAvailableComponentInstanceId } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceId'; import { useAvailableComponentInstanceId } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceId';
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
@ -30,7 +30,7 @@ export const useCloseDropdown = () => {
const isDropdownOpen = snapshot const isDropdownOpen = snapshot
.getLoadable( .getLoadable(
isDropdownOpenComponentStateV2.atomFamily({ isDropdownOpenComponentState.atomFamily({
instanceId: dropdownComponentInstanceId, instanceId: dropdownComponentInstanceId,
}), }),
) )
@ -44,7 +44,7 @@ export const useCloseDropdown = () => {
goBackToPreviousDropdownFocusId(); goBackToPreviousDropdownFocusId();
set( set(
isDropdownOpenComponentStateV2.atomFamily({ isDropdownOpenComponentState.atomFamily({
instanceId: dropdownComponentInstanceId, instanceId: dropdownComponentInstanceId,
}), }),
false, false,

View File

@ -1,110 +0,0 @@
import { useRecoilCallback } from 'recoil';
import { useDropdownStates } from '@/ui/layout/dropdown/hooks/internal/useDropdownStates';
import { useGoBackToPreviousDropdownFocusId } from '@/ui/layout/dropdown/hooks/useGoBackToPreviousDropdownFocusId';
import { useSetActiveDropdownFocusIdAndMemorizePrevious } from '@/ui/layout/dropdown/hooks/useSetFocusedDropdownIdAndMemorizePrevious';
import { dropdownPlacementComponentStateV2 } from '@/ui/layout/dropdown/states/dropdownPlacementComponentStateV2';
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2';
import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack';
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
import { GlobalHotkeysConfig } from '@/ui/utilities/hotkey/types/GlobalHotkeysConfig';
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2';
import { useCallback } from 'react';
/**
*
* @deprecated This hook is deprecated, use a specific hook instead :
* - `useOpenDropdown`
* - `useCloseDropdown`
* - `useToggleDropdown`
*/
export const useDropdown = (dropdownId?: string) => {
const { pushFocusItemToFocusStack } = usePushFocusItemToFocusStack();
const { removeFocusItemFromFocusStackById } =
useRemoveFocusItemFromFocusStackById();
const { scopeId } = useDropdownStates({ dropdownScopeId: dropdownId });
const { setActiveDropdownFocusIdAndMemorizePrevious } =
useSetActiveDropdownFocusIdAndMemorizePrevious();
const { goBackToPreviousDropdownFocusId } =
useGoBackToPreviousDropdownFocusId();
const [isDropdownOpen, setIsDropdownOpen] = useRecoilComponentStateV2(
isDropdownOpenComponentStateV2,
dropdownId ?? scopeId,
);
const [dropdownPlacement, setDropdownPlacement] = useRecoilComponentStateV2(
dropdownPlacementComponentStateV2,
dropdownId ?? scopeId,
);
const closeDropdown = useCallback(() => {
if (isDropdownOpen) {
setIsDropdownOpen(false);
goBackToPreviousDropdownFocusId();
removeFocusItemFromFocusStackById({
focusId: dropdownId ?? scopeId,
});
}
}, [
isDropdownOpen,
setIsDropdownOpen,
goBackToPreviousDropdownFocusId,
removeFocusItemFromFocusStackById,
dropdownId,
scopeId,
]);
const openDropdown = useRecoilCallback(
() => (globalHotkeysConfig?: Partial<GlobalHotkeysConfig>) => {
if (!isDropdownOpen) {
setIsDropdownOpen(true);
setActiveDropdownFocusIdAndMemorizePrevious(dropdownId ?? scopeId);
pushFocusItemToFocusStack({
focusId: dropdownId ?? scopeId,
component: {
type: FocusComponentType.DROPDOWN,
instanceId: dropdownId ?? scopeId,
},
globalHotkeysConfig,
// TODO: Remove this once we've fully migrated away from hotkey scopes
hotkeyScope: { scope: 'dropdown' } as HotkeyScope,
});
}
},
[
isDropdownOpen,
setIsDropdownOpen,
setActiveDropdownFocusIdAndMemorizePrevious,
pushFocusItemToFocusStack,
dropdownId,
scopeId,
],
);
const toggleDropdown = (
globalHotkeysConfig?: Partial<GlobalHotkeysConfig>,
) => {
if (isDropdownOpen) {
closeDropdown();
} else {
openDropdown(globalHotkeysConfig);
}
};
return {
scopeId,
isDropdownOpen,
closeDropdown,
toggleDropdown,
openDropdown,
dropdownPlacement,
setDropdownPlacement,
};
};

View File

@ -1,7 +1,7 @@
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext'; import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
import { useSetActiveDropdownFocusIdAndMemorizePrevious } from '@/ui/layout/dropdown/hooks/useSetFocusedDropdownIdAndMemorizePrevious'; import { useSetActiveDropdownFocusIdAndMemorizePrevious } from '@/ui/layout/dropdown/hooks/useSetFocusedDropdownIdAndMemorizePrevious';
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2'; import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack'; import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack';
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType'; import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
import { GlobalHotkeysConfig } from '@/ui/utilities/hotkey/types/GlobalHotkeysConfig'; import { GlobalHotkeysConfig } from '@/ui/utilities/hotkey/types/GlobalHotkeysConfig';
@ -35,7 +35,7 @@ export const useOpenDropdown = () => {
} }
set( set(
isDropdownOpenComponentStateV2.atomFamily({ isDropdownOpenComponentState.atomFamily({
instanceId: dropdownComponentInstanceId, instanceId: dropdownComponentInstanceId,
}), }),
true, true,

View File

@ -1,7 +1,7 @@
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext'; import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown'; import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown'; import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2'; import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { GlobalHotkeysConfig } from '@/ui/utilities/hotkey/types/GlobalHotkeysConfig'; import { GlobalHotkeysConfig } from '@/ui/utilities/hotkey/types/GlobalHotkeysConfig';
import { useAvailableComponentInstanceId } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceId'; import { useAvailableComponentInstanceId } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceId';
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
@ -32,7 +32,7 @@ export const useToggleDropdown = () => {
const isDropdownOpen = snapshot const isDropdownOpen = snapshot
.getLoadable( .getLoadable(
isDropdownOpenComponentStateV2.atomFamily({ isDropdownOpenComponentState.atomFamily({
instanceId: dropdownComponentInstanceId, instanceId: dropdownComponentInstanceId,
}), }),
) )

View File

@ -3,7 +3,7 @@ import { createComponentStateV2 } from '@/ui/utilities/state/component-state/uti
import { Placement } from '@floating-ui/react'; import { Placement } from '@floating-ui/react';
export const dropdownPlacementComponentStateV2 = export const dropdownPlacementComponentState =
createComponentStateV2<Placement | null>({ createComponentStateV2<Placement | null>({
key: 'dropdownPlacementComponentState', key: 'dropdownPlacementComponentState',
componentInstanceContext: DropdownComponentInstanceContext, componentInstanceContext: DropdownComponentInstanceContext,

View File

@ -1,8 +1,8 @@
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext'; import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2'; import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
export const isDropdownOpenComponentStateV2 = createComponentStateV2<boolean>({ export const isDropdownOpenComponentState = createComponentStateV2<boolean>({
key: 'isDropdownOpenComponentStateV2', key: 'isDropdownOpenComponentState',
defaultValue: false, defaultValue: false,
componentInstanceContext: DropdownComponentInstanceContext, componentInstanceContext: DropdownComponentInstanceContext,
}); });

View File

@ -1,12 +1,12 @@
import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton'; import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton';
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2'; import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { VIEW_BAR_FILTER_DROPDOWN_ID } from '@/views/constants/ViewBarFilterDropdownId'; import { VIEW_BAR_FILTER_DROPDOWN_ID } from '@/views/constants/ViewBarFilterDropdownId';
import { Trans } from '@lingui/react/macro'; import { Trans } from '@lingui/react/macro';
export const ViewBarFilterButton = () => { export const ViewBarFilterButton = () => {
const isDropdownOpen = useRecoilComponentValueV2( const isDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentStateV2, isDropdownOpenComponentState,
VIEW_BAR_FILTER_DROPDOWN_ID, VIEW_BAR_FILTER_DROPDOWN_ID,
); );

View File

@ -3,7 +3,7 @@ import styled from '@emotion/styled';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { StyledDropdownButtonContainer } from '@/ui/layout/dropdown/components/StyledDropdownButtonContainer'; import { StyledDropdownButtonContainer } from '@/ui/layout/dropdown/components/StyledDropdownButtonContainer';
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2'; import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { useGetRecordIndexTotalCount } from '@/views/hooks/internal/useGetRecordIndexTotalCount'; import { useGetRecordIndexTotalCount } from '@/views/hooks/internal/useGetRecordIndexTotalCount';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly'; import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
@ -53,7 +53,7 @@ export const ViewPickerDropdown = () => {
const { totalCount } = useGetRecordIndexTotalCount(); const { totalCount } = useGetRecordIndexTotalCount();
const isDropdownOpen = useRecoilComponentValueV2( const isDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentStateV2, isDropdownOpenComponentState,
VIEW_PICKER_DROPDOWN_ID, VIEW_PICKER_DROPDOWN_ID,
); );

View File

@ -4,7 +4,7 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth'; import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown'; import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown'; import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2'; import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2'; import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
import { WORKFLOW_DIAGRAM_EDGE_OPTIONS_CLICK_OUTSIDE_ID } from '@/workflow/workflow-diagram/constants/WorkflowDiagramEdgeOptionsClickOutsideId'; import { WORKFLOW_DIAGRAM_EDGE_OPTIONS_CLICK_OUTSIDE_ID } from '@/workflow/workflow-diagram/constants/WorkflowDiagramEdgeOptionsClickOutsideId';
@ -95,7 +95,7 @@ export const WorkflowDiagramEdgeV2Content = ({
const dropdownId = `${WORKFLOW_DIAGRAM_EDGE_OPTIONS_CLICK_OUTSIDE_ID}-${parentStepId}-${nextStepId}`; const dropdownId = `${WORKFLOW_DIAGRAM_EDGE_OPTIONS_CLICK_OUTSIDE_ID}-${parentStepId}-${nextStepId}`;
const isDropdownOpen = useRecoilComponentValueV2( const isDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentStateV2, isDropdownOpenComponentState,
dropdownId, dropdownId,
); );

View File

@ -1,7 +1,7 @@
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { StyledDropdownButtonContainer } from '@/ui/layout/dropdown/components/StyledDropdownButtonContainer'; import { StyledDropdownButtonContainer } from '@/ui/layout/dropdown/components/StyledDropdownButtonContainer';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown'; import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2'; import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { WorkflowVariablesDropdownFieldItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownFieldItems'; import { WorkflowVariablesDropdownFieldItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownFieldItems';
import { WorkflowVariablesDropdownObjectItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownObjectItems'; import { WorkflowVariablesDropdownObjectItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownObjectItems';
@ -48,7 +48,7 @@ export const WorkflowVariablesDropdown = ({
const dropdownId = `${SEARCH_VARIABLES_DROPDOWN_ID}-${instanceId}`; const dropdownId = `${SEARCH_VARIABLES_DROPDOWN_ID}-${instanceId}`;
const isDropdownOpen = useRecoilComponentValueV2( const isDropdownOpen = useRecoilComponentValueV2(
isDropdownOpenComponentStateV2, isDropdownOpenComponentState,
dropdownId, dropdownId,
); );
const { closeDropdown } = useCloseDropdown(); const { closeDropdown } = useCloseDropdown();