diff --git a/src/components/ButtonWithDropdownMenu/index.tsx b/src/components/ButtonWithDropdownMenu/index.tsx index 3c750512be87..afe40ec903ef 100644 --- a/src/components/ButtonWithDropdownMenu/index.tsx +++ b/src/components/ButtonWithDropdownMenu/index.tsx @@ -184,6 +184,7 @@ function ButtonWithDropdownMenu({ref, ...props}: ButtonWithDropdownM innerStyles={[innerStyleDropButton, !isSplitButton && styles.dropDownButtonCartIconView, isTextTooLong && shouldUseShortForm && {...styles.pl2, ...styles.pr1}]} enterKeyEventListenerPriority={enterKeyEventListenerPriority} iconRight={icons.DownArrow} + iconRightStyles={isMenuVisible ? styles.flipUpsideDown : undefined} shouldShowRightIcon={!isSplitButton && !isLoading && options?.length > 0} testID={testID} textStyles={[isTextTooLong && shouldUseShortForm ? {...styles.textExtraSmall, ...styles.textBold} : {}]} @@ -229,8 +230,9 @@ function ButtonWithDropdownMenu({ref, ...props}: ButtonWithDropdownM width={shouldUseShortForm ? variables.iconSizeExtraSmall : undefined} height={shouldUseShortForm ? variables.iconSizeExtraSmall : undefined} src={icons.DownArrow} - additionalStyles={shouldUseShortForm ? [styles.pRelative, styles.t0] : undefined} + additionalStyles={[...(shouldUseShortForm ? [styles.pRelative, styles.t0] : []), isMenuVisible ? styles.flipUpsideDown : undefined]} fill={success ? theme.buttonSuccessText : theme.icon} + testID="dropdown-arrow-icon" /> diff --git a/tests/ui/components/ButtonWithDropdownMenuTest.tsx b/tests/ui/components/ButtonWithDropdownMenuTest.tsx index 4d62cc63cf68..55a8d989ad00 100644 --- a/tests/ui/components/ButtonWithDropdownMenuTest.tsx +++ b/tests/ui/components/ButtonWithDropdownMenuTest.tsx @@ -67,3 +67,59 @@ describe('ButtonWithDropdownMenu (single option)', () => { expect(screen.getByText('Test Option')).toBeTruthy(); }); }); + +describe('ButtonWithDropdownMenu (dropdown arrow flip)', () => { + const mockOnPress = jest.fn(); + const {result: icons} = renderHook(() => useMemoizedLazyExpensifyIcons(['Checkbox'])); + const options = [ + {value: 'one', text: 'Option One', icon: icons.current.Checkbox}, + {value: 'two', text: 'Option Two', icon: icons.current.Checkbox}, + ]; + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('flips the arrow icon when the dropdown menu is opened in split button mode', () => { + render( + , + ); + + const arrowIcon = screen.getByTestId('dropdown-arrow-icon', {includeHiddenElements: true}); + expect(arrowIcon).not.toHaveStyle({transform: 'rotate(180deg)'}); + + const buttons = screen.getAllByRole('button'); + const buttonToPress = buttons?.at(1); + if (buttonToPress) { + fireEvent.press(buttonToPress); + } + expect(arrowIcon).toHaveStyle({transform: 'rotate(180deg)'}); + }); + + it('reverts the arrow icon when the dropdown menu is closed', () => { + render( + , + ); + + const arrowIcon = screen.getByTestId('dropdown-arrow-icon', {includeHiddenElements: true}); + const buttons = screen.getAllByRole('button'); + const buttonToPress = buttons?.at(1); + if (buttonToPress) { + fireEvent.press(buttonToPress); + } + expect(arrowIcon).toHaveStyle({transform: 'rotate(180deg)'}); + + if (buttonToPress) { + fireEvent.press(buttonToPress); + } + expect(arrowIcon).not.toHaveStyle({transform: 'rotate(180deg)'}); + }); +});