diff --git a/packages/twenty-front/src/modules/action-menu/components/RecordIndexActionMenuDropdown.tsx b/packages/twenty-front/src/modules/action-menu/components/RecordIndexActionMenuDropdown.tsx index 1b91826c2..43d303549 100644 --- a/packages/twenty-front/src/modules/action-menu/components/RecordIndexActionMenuDropdown.tsx +++ b/packages/twenty-front/src/modules/action-menu/components/RecordIndexActionMenuDropdown.tsx @@ -5,30 +5,22 @@ import { ActionMenuDropdownHotkeyScope } from '@/action-menu/types/ActionMenuDro import { getActionMenuDropdownIdFromActionMenuId } from '@/action-menu/utils/getActionMenuDropdownIdFromActionMenuId'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; +import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState'; import styled from '@emotion/styled'; import { useRecoilValue } from 'recoil'; import { MenuItem } from 'twenty-ui'; -import { PositionType } from '../types/PositionType'; -type StyledContainerProps = { - position: PositionType; -}; +const StyledDropdownMenuContainer = styled.div` + width: 100%; + height: 100%; -const StyledContainerActionMenuDropdown = styled.div` - align-items: flex-start; display: flex; flex-direction: column; - - left: ${(props) => `${props.position.x}px`}; - position: fixed; - top: ${(props) => `${props.position.y}px`}; - - transform: translateX(-50%); - width: 0; - height: 0; + justify-content: center; + align-items: center; `; export const RecordIndexActionMenuDropdown = () => { @@ -40,10 +32,13 @@ export const RecordIndexActionMenuDropdown = () => { ActionMenuComponentInstanceContext, ); + const dropdownId = getActionMenuDropdownIdFromActionMenuId(actionMenuId); + const { closeDropdown } = useDropdown(dropdownId); + const actionMenuDropdownPosition = useRecoilValue( extractComponentState( recordIndexActionMenuDropdownPositionComponentState, - getActionMenuDropdownIdFromActionMenuId(actionMenuId), + dropdownId, ), ); @@ -55,32 +50,37 @@ export const RecordIndexActionMenuDropdown = () => { : undefined; return ( - - - {actionMenuEntries.map((item, index) => ( + {actionMenuEntries.map((item) => ( { + item.onClick?.(); + closeDropdown(); + }} accent={item.accent} text={item.label} /> ))} - } - avoidPortal - /> - + + } + /> ); }; diff --git a/packages/twenty-front/src/modules/action-menu/components/__stories__/RecordIndexActionMenuDropdown.stories.tsx b/packages/twenty-front/src/modules/action-menu/components/__stories__/RecordIndexActionMenuDropdown.stories.tsx index c319f04e1..afdec02e7 100644 --- a/packages/twenty-front/src/modules/action-menu/components/__stories__/RecordIndexActionMenuDropdown.stories.tsx +++ b/packages/twenty-front/src/modules/action-menu/components/__stories__/RecordIndexActionMenuDropdown.stories.tsx @@ -120,13 +120,5 @@ export const WithInteractions: Story = { const deleteButton = await canvas.findByText('Delete'); await userEvent.click(deleteButton); expect(deleteMock).toHaveBeenCalled(); - - const markAsDoneButton = await canvas.findByText('Mark as done'); - await userEvent.click(markAsDoneButton); - expect(markAsDoneMock).toHaveBeenCalled(); - - const addToFavoritesButton = await canvas.findByText('Add to favorites'); - await userEvent.click(addToFavoritesButton); - expect(addToFavoritesMock).toHaveBeenCalled(); }, }; diff --git a/packages/twenty-front/src/modules/ui/field/display/components/ArrayDisplay.tsx b/packages/twenty-front/src/modules/ui/field/display/components/ArrayDisplay.tsx index 96b5d4c16..2b662bdd2 100644 --- a/packages/twenty-front/src/modules/ui/field/display/components/ArrayDisplay.tsx +++ b/packages/twenty-front/src/modules/ui/field/display/components/ArrayDisplay.tsx @@ -10,8 +10,12 @@ type ArrayDisplayProps = { export const ArrayDisplay = ({ value }: ArrayDisplayProps) => { return ( - {value?.map((item) => ( - + {value?.map((item, index) => ( + ))} ); diff --git a/packages/twenty-front/src/modules/ui/layout/dropdown/components/Dropdown.tsx b/packages/twenty-front/src/modules/ui/layout/dropdown/components/Dropdown.tsx index f3bf97d0d..0b0c1185a 100644 --- a/packages/twenty-front/src/modules/ui/layout/dropdown/components/Dropdown.tsx +++ b/packages/twenty-front/src/modules/ui/layout/dropdown/components/Dropdown.tsx @@ -19,10 +19,17 @@ import { DropdownUnmountEffect } from '@/ui/layout/dropdown/components/DropdownU import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponeInstanceContext'; import { dropdownMaxHeightComponentStateV2 } from '@/ui/layout/dropdown/states/dropdownMaxHeightComponentStateV2'; import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2'; +import styled from '@emotion/styled'; import { flushSync } from 'react-dom'; import { isDefined } from 'twenty-ui'; import { DropdownOnToggleEffect } from './DropdownOnToggleEffect'; +const StyledDropdownFallbackAnchor = styled.div` + left: 0; + position: absolute; + top: 0; +`; + type DropdownProps = { className?: string; clickableComponent?: ReactNode; @@ -53,7 +60,7 @@ export const Dropdown = ({ dropdownHotkeyScope, dropdownPlacement = 'bottom-end', dropdownStrategy = 'absolute', - dropdownOffset = { x: 0, y: 0 }, + dropdownOffset, onClickOutside, onClose, onOpen, @@ -61,24 +68,27 @@ export const Dropdown = ({ }: DropdownProps) => { const { isDropdownOpen, toggleDropdown } = useDropdown(dropdownId); - const offsetMiddlewares = []; - const setDropdownMaxHeight = useSetRecoilComponentStateV2( dropdownMaxHeightComponentStateV2, dropdownId, ); - if (isDefined(dropdownOffset.x)) { - offsetMiddlewares.push(offset({ crossAxis: dropdownOffset.x })); - } + const isUsingOffset = + isDefined(dropdownOffset?.x) || isDefined(dropdownOffset?.y); - if (isDefined(dropdownOffset.y)) { - offsetMiddlewares.push(offset({ mainAxis: dropdownOffset.y })); - } + const offsetMiddleware = isUsingOffset + ? [ + offset({ + crossAxis: dropdownOffset?.x ?? 0, + mainAxis: dropdownOffset?.y ?? 0, + }), + ] + : []; const { refs, floatingStyles, placement } = useFloating({ placement: dropdownPlacement, middleware: [ + ...offsetMiddleware, flip(), size({ padding: 32, @@ -89,7 +99,6 @@ export const Dropdown = ({ }, boundary: document.querySelector('#root') ?? undefined, }), - ...offsetMiddlewares, ], whileElementsMounted: autoUpdate, strategy: dropdownStrategy, @@ -109,13 +118,15 @@ export const Dropdown = ({ > <> - {clickableComponent && ( + {isDefined(clickableComponent) ? (
{clickableComponent}
+ ) : ( + )} {isDropdownOpen && (