From 3893b26d302f76df0d0d7c51ab8ea91a0778d4fa Mon Sep 17 00:00:00 2001 From: Matthew Russell Date: Thu, 26 Jan 2023 00:52:49 -0800 Subject: [PATCH] fix: dropdown menu portals (#2740) --- .../portfolio/account-history-container.tsx | 34 ++++++++++------- .../vega-wallet-connect-button.spec.tsx | 5 ++- .../vega-wallet-connect-button.tsx | 24 +++++++----- libs/candles-chart/src/lib/candles-chart.tsx | 32 ++++++++++------ .../network-switcher/network-switcher.tsx | 19 ++++++---- .../dropdown-menu/dropdown-menu.spec.tsx | 34 +++++++++++++++++ .../dropdown-menu/dropdown-menu.stories.tsx | 37 ++++++++++++------- .../dropdown-menu/dropdown-menu.tsx | 18 ++++++++- 8 files changed, 144 insertions(+), 59 deletions(-) create mode 100644 libs/ui-toolkit/src/components/dropdown-menu/dropdown-menu.spec.tsx diff --git a/apps/trading/client-pages/portfolio/account-history-container.tsx b/apps/trading/client-pages/portfolio/account-history-container.tsx index a414bb8bc..04a44fb7a 100644 --- a/apps/trading/client-pages/portfolio/account-history-container.tsx +++ b/apps/trading/client-pages/portfolio/account-history-container.tsx @@ -139,16 +139,19 @@ const AccountHistoryManager = ({
- - - {accountType - ? `${ - AccountTypeMapping[ - accountType as keyof typeof Schema.AccountType - ] - } Account` - : t('Select account type')} - + + {accountType + ? `${ + AccountTypeMapping[ + accountType as keyof typeof Schema.AccountType + ] + } Account` + : t('Select account type')} + + } + > {[ Schema.AccountType.ACCOUNT_TYPE_GENERAL, @@ -164,10 +167,13 @@ const AccountHistoryManager = ({ ))} - - - {asset ? asset.symbol : t('Select asset')} - + + {asset ? asset.symbol : t('Select asset')} + + } + > {assets.map((a) => ( setAsset(a)}> diff --git a/apps/trading/components/vega-wallet-connect-button/vega-wallet-connect-button.spec.tsx b/apps/trading/components/vega-wallet-connect-button/vega-wallet-connect-button.spec.tsx index e5f2cc19c..255b5336a 100644 --- a/apps/trading/components/vega-wallet-connect-button/vega-wallet-connect-button.spec.tsx +++ b/apps/trading/components/vega-wallet-connect-button/vega-wallet-connect-button.spec.tsx @@ -3,6 +3,7 @@ import { VegaWalletContext } from '@vegaprotocol/wallet'; import type { VegaWalletContextShape } from '@vegaprotocol/wallet'; import { VegaWalletConnectButton } from './vega-wallet-connect-button'; import { truncateByChars } from '@vegaprotocol/react-helpers'; +import userEvent from '@testing-library/user-event'; const mockUpdateDialogOpen = jest.fn(); jest.mock('@vegaprotocol/wallet', () => ({ @@ -31,7 +32,7 @@ it('Not connected', () => { expect(mockUpdateDialogOpen).toHaveBeenCalled(); }); -it('Connected', () => { +it('Connected', async () => { const pubKey = { publicKey: '123456__123456', name: 'test' }; render( generateJsx({ @@ -42,6 +43,6 @@ it('Connected', () => { const button = screen.getByTestId('manage-vega-wallet'); expect(button).toHaveTextContent(truncateByChars(pubKey.publicKey)); - fireEvent.click(button); + userEvent.click(button); expect(mockUpdateDialogOpen).not.toHaveBeenCalled(); }); diff --git a/apps/trading/components/vega-wallet-connect-button/vega-wallet-connect-button.tsx b/apps/trading/components/vega-wallet-connect-button/vega-wallet-connect-button.tsx index 7833ca1b3..1109b61be 100644 --- a/apps/trading/components/vega-wallet-connect-button/vega-wallet-connect-button.tsx +++ b/apps/trading/components/vega-wallet-connect-button/vega-wallet-connect-button.tsx @@ -142,15 +142,21 @@ export const VegaWalletConnectButton = () => { return ( <>
- - setDropdownOpen((curr) => !curr)} - > - {activeKey && {activeKey.name}} - {': '} - {truncateByChars(pubKey)} - + setDropdownOpen((curr) => !curr)} + > + {activeKey && ( + {activeKey.name} + )} + {': '} + {truncateByChars(pubKey)} + + } + > setDropdownOpen(false)} > diff --git a/libs/candles-chart/src/lib/candles-chart.tsx b/libs/candles-chart/src/lib/candles-chart.tsx index 04ad908ab..abd873c9c 100644 --- a/libs/candles-chart/src/lib/candles-chart.tsx +++ b/libs/candles-chart/src/lib/candles-chart.tsx @@ -60,10 +60,13 @@ export const CandlesChartContainer = ({ return (
- - - {t(`Interval: ${intervalLabels[interval]}`)} - + + {t(`Interval: ${intervalLabels[interval]}`)} + + } + > - - - - + + + + } + > - - {t('Overlays')} + {t('Overlays')}} + > {Object.values(Overlay).map((overlay) => ( - - {t('Studies')} + {t('Studies')}} + > {Object.values(Study).map((study) => ( { const menuRef = useRef(null); return ( - - - {envTriggerMapping[VEGA_ENV]} - + + {envTriggerMapping[VEGA_ENV]} + + } + > { + const text = 'Dropdown menu content'; + + // Upgrade from @radix-ui/react-dropdown-menu 0.1.6 to 2.0.2 renders + // dropdowns inline (rather than portals). Currently not using a portal + // will break the UI due to z-index issues + it('renders using a portal', async () => { + render( +
+ Trigger} + > + +

{text}

+
+
+
+ ); + + userEvent.click(screen.getByText(/trigger/i)); + const contentElement = await screen.findByText(text); + expect(contentElement).toBeInTheDocument(); + // if content is within .test-wrapper then its not been rendered in a portal + expect(contentElement.closest('.test-wrapper')).toBe(null); + }); +}); diff --git a/libs/ui-toolkit/src/components/dropdown-menu/dropdown-menu.stories.tsx b/libs/ui-toolkit/src/components/dropdown-menu/dropdown-menu.stories.tsx index 1c8fcce22..66aef069e 100644 --- a/libs/ui-toolkit/src/components/dropdown-menu/dropdown-menu.stories.tsx +++ b/libs/ui-toolkit/src/components/dropdown-menu/dropdown-menu.stories.tsx @@ -29,16 +29,21 @@ export const CheckboxItems = () => { console.log(checkboxItems); return ( - - - Select many things - + + Select many things + + } + > {checkboxItems.map(({ label, state: [checked, setChecked] }) => ( + setChecked(typeof checked === 'boolean' ? checked : false) + } > {label} @@ -55,10 +60,13 @@ export const RadioItems = () => { return (
- - - Open - + + Open + + } + > console.log('minimize')}> Minimize window @@ -92,10 +100,13 @@ export const IconMenu = () => { return (
- - - - + + + + } + > {iconMenuItems.map(({ label }) => ( {label} diff --git a/libs/ui-toolkit/src/components/dropdown-menu/dropdown-menu.tsx b/libs/ui-toolkit/src/components/dropdown-menu/dropdown-menu.tsx index 906efc934..8c000a171 100644 --- a/libs/ui-toolkit/src/components/dropdown-menu/dropdown-menu.tsx +++ b/libs/ui-toolkit/src/components/dropdown-menu/dropdown-menu.tsx @@ -1,5 +1,6 @@ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'; import classNames from 'classnames'; +import type { ReactNode } from 'react'; import { forwardRef } from 'react'; import { Icon } from '../icon'; @@ -12,11 +13,24 @@ const itemClass = classNames( 'whitespace-nowrap' ); +type DropdownMenuProps = DropdownMenuPrimitive.DropdownMenuProps & { + trigger: ReactNode; +}; /** * Contains all the parts of a dropdown menu. */ -export const DropdownMenu = DropdownMenuPrimitive.Root; - +export const DropdownMenu = ({ + children, + trigger, + ...props +}: DropdownMenuProps) => { + return ( + + {trigger} + {children} + + ); +}; /** * The button that toggles the dropdown menu. * By default, the {@link DropdownMenuContent} will position itself against the trigger.