diff --git a/src/wallet/components/WalletDropdown.test.tsx b/src/wallet/components/WalletDropdown.test.tsx index cbc9030db8..7554aee856 100644 --- a/src/wallet/components/WalletDropdown.test.tsx +++ b/src/wallet/components/WalletDropdown.test.tsx @@ -1,65 +1,64 @@ import '@testing-library/jest-dom'; -import { render, renderHook, screen, waitFor } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; import { useAccount } from 'wagmi'; -import { Identity } from '../../identity/components/Identity'; -import { - IdentityProvider, - useIdentityContext, -} from '../../identity/components/IdentityProvider'; +import useBreakpoints from '../../useBreakpoints'; import { WalletDropdown } from './WalletDropdown'; -import { useWalletContext } from './WalletProvider'; vi.mock('wagmi', () => ({ useAccount: vi.fn(), })); -vi.mock('./WalletProvider', () => ({ - useWalletContext: vi.fn(), +vi.mock('../../useBreakpoints', () => ({ + default: vi.fn(), })); -vi.mock('../../identity/components/Identity', () => ({ - Identity: vi.fn(({ address, children }) => ( - {children} - )), -})); - -const useWalletContextMock = useWalletContext as vi.Mock; const useAccountMock = useAccount as vi.Mock; +const useBreakpointsMock = useBreakpoints as vi.Mock; describe('WalletDropdown', () => { - it('renders null when address is not provided', () => { - useWalletContextMock.mockReturnValue({ isOpen: true }); + beforeEach(() => { + vi.clearAllMocks(); + }); + + it('does not render anything if address is not available', () => { useAccountMock.mockReturnValue({ address: null }); + useBreakpointsMock.mockReturnValue('sm'); + + render(Content); + + expect(screen.queryByText('Content')).not.toBeInTheDocument(); + }); - render(Test Children); + it('does not render anything if breakpoint is not defined', () => { + useAccountMock.mockReturnValue({ address: '0x123' }); + useBreakpointsMock.mockReturnValue(null); + + render(Content); - expect(screen.queryByText('Test Children')).not.toBeInTheDocument(); + expect(screen.queryByText('Content')).not.toBeInTheDocument(); }); - it('renders children when isOpen is true and address is provided', () => { - useWalletContextMock.mockReturnValue({ isOpen: true }); + it('renders WalletBottomSheet when breakpoint is "sm"', () => { useAccountMock.mockReturnValue({ address: '0x123' }); + useBreakpointsMock.mockReturnValue('sm'); - render(Test Children); + render(Content); - expect(screen.getByText('Test Children')).toBeInTheDocument(); + const bottomSheet = screen.getByTestId('ockWalletBottomSheet'); + + expect(bottomSheet).toBeInTheDocument(); + expect(bottomSheet).toHaveClass('bottom-sheet'); }); - it('injects address prop to Identity component', async () => { - const address = '0x123'; - useWalletContextMock.mockReturnValue({ isOpen: true }); - useAccountMock.mockReturnValue({ address }); - - const { result } = renderHook(() => useIdentityContext(), { - wrapper: ({ children }) => ( - - {children} - - ), - }); - - await waitFor(() => { - expect(result.current.address).toEqual(address); - }); + it('renders WalletDropdown when breakpoint is not "sm"', () => { + useAccountMock.mockReturnValue({ address: '0x123' }); + useBreakpointsMock.mockReturnValue('md'); + + render(Content); + + const dropdown = screen.getByTestId('ockWalletDropdown'); + + expect(dropdown).toBeInTheDocument(); + expect(dropdown).toHaveClass('dropdown'); }); }); diff --git a/src/wallet/components/WalletDropdown.tsx b/src/wallet/components/WalletDropdown.tsx index 6f98a6dbfe..6fe56bd2a0 100644 --- a/src/wallet/components/WalletDropdown.tsx +++ b/src/wallet/components/WalletDropdown.tsx @@ -1,10 +1,13 @@ import { Children, cloneElement, isValidElement, useMemo } from 'react'; import { useAccount } from 'wagmi'; +import useBreakpoints from '../../useBreakpoints'; import { Identity } from '../../identity/components/Identity'; import { background, cn } from '../../styles/theme'; import type { WalletDropdownReact } from '../types'; +import { WalletBottomSheet } from './WalletBottomSheet'; export function WalletDropdown({ children, className }: WalletDropdownReact) { + const breakpoint = useBreakpoints(); const { address } = useAccount(); const childrenArray = useMemo(() => { @@ -21,6 +24,16 @@ export function WalletDropdown({ children, className }: WalletDropdownReact) { return null; } + if (!breakpoint) { + return null; + } + + if (breakpoint === 'sm') { + return ( + {children} + ); + } + return (
({ - useAccount: vi.fn(), -})); - -vi.mock('../../useBreakpoints', () => ({ - default: vi.fn(), -})); - -const useAccountMock = useAccount as vi.Mock; -const useBreakpointsMock = useBreakpoints as vi.Mock; - -describe('WalletMenu', () => { - beforeEach(() => { - vi.clearAllMocks(); - }); - - it('does not render anything if address is not available', () => { - useAccountMock.mockReturnValue({ address: null }); - useBreakpointsMock.mockReturnValue('sm'); - - render(Content); - - expect(screen.queryByText('Content')).not.toBeInTheDocument(); - }); - - it('does not render anything if breakpoint is not defined', () => { - useAccountMock.mockReturnValue({ address: '0x123' }); - useBreakpointsMock.mockReturnValue(null); - - render(Content); - - expect(screen.queryByText('Content')).not.toBeInTheDocument(); - }); - - it('renders WalletBottomSheet when breakpoint is "sm"', () => { - useAccountMock.mockReturnValue({ address: '0x123' }); - useBreakpointsMock.mockReturnValue('sm'); - - render(Content); - - const bottomSheet = screen.getByTestId('ockWalletBottomSheet'); - expect(bottomSheet).toBeInTheDocument(); - expect(bottomSheet).toHaveClass('bottom-sheet'); - }); - - it('renders WalletDropdown when breakpoint is not "sm"', () => { - useAccountMock.mockReturnValue({ address: '0x123' }); - useBreakpointsMock.mockReturnValue('md'); - - render(Content); - - const dropdown = screen.getByTestId('ockWalletDropdown'); - - expect(dropdown).toBeInTheDocument(); - expect(dropdown).toHaveClass('dropdown'); - }); -}); diff --git a/src/wallet/components/WalletMenu.tsx b/src/wallet/components/WalletMenu.tsx deleted file mode 100644 index aca6090cc1..0000000000 --- a/src/wallet/components/WalletMenu.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { useAccount } from 'wagmi'; -import useBreakpoints from '../../useBreakpoints'; -import type { WalletMenuReact } from '../types'; -import { WalletBottomSheet } from './WalletBottomSheet'; -import { WalletDropdown } from './WalletDropdown'; - -export function WalletMenu({ children, className }: WalletMenuReact) { - const breakpoint = useBreakpoints(); - const { address } = useAccount(); - if (!address) { - return null; - } - - if (!breakpoint) { - return null; - } - - if (breakpoint === 'sm') { - return ( - {children} - ); - } - - return {children}; -} diff --git a/src/wallet/components/WalletWithMobileDrawer.test.tsx b/src/wallet/components/WalletWithMobileDrawer.test.tsx deleted file mode 100644 index eaf18e9961..0000000000 --- a/src/wallet/components/WalletWithMobileDrawer.test.tsx +++ /dev/null @@ -1,138 +0,0 @@ -import { fireEvent, render, screen } from '@testing-library/react'; -import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { useAccount } from 'wagmi'; -import useBreakpoints from '../../useBreakpoints'; -import { ConnectWallet } from './ConnectWallet'; -import { WalletMenu } from './WalletMenu'; -import { useWalletContext } from './WalletProvider'; -import { WalletWithMobileDrawer } from './WalletWithMobileDrawer'; - -vi.mock('./WalletProvider', () => ({ - useWalletContext: vi.fn(), - WalletProvider: ({ children }) => <>{children}, -})); - -vi.mock('./ConnectWallet', () => ({ - ConnectWallet: () =>
Connect Wallet
, -})); - -vi.mock('./WalletDropdown', () => ({ - WalletDropdown: () => ( -
Wallet Dropdown
- ), -})); - -vi.mock('wagmi', () => ({ - useAccount: vi.fn(), -})); - -vi.mock('../../useBreakpoints', () => ({ - default: vi.fn(), -})); - -const useAccountMock = useAccount as vi.Mock; -const useBreakpointsMock = useBreakpoints as vi.Mock; - -describe('WalletWithMobileDrawer Component', () => { - let mockSetIsOpen: ReturnType; - - beforeEach(() => { - mockSetIsOpen = vi.fn(); - (useWalletContext as ReturnType).mockReturnValue({ - isOpen: false, - setIsOpen: mockSetIsOpen, - }); - }); - - it('should render the Wallet component with ConnectWallet', () => { - render( - - - - , - ); - - expect(screen.getByTestId('connect-wallet')).toBeDefined(); - expect(screen.queryByTestId('wallet-dropdown')).toBeNull(); - }); - - it('should close the wallet when clicking outside', () => { - (useWalletContext as ReturnType).mockReturnValue({ - isOpen: true, - setIsOpen: mockSetIsOpen, - }); - - useAccountMock.mockReturnValue({ address: '123' }); - useBreakpointsMock.mockReturnValue('sm'); - - render( - - - - , - ); - - expect(screen.getByTestId('ockWalletBottomSheet')).toBeDefined(); - - fireEvent.click(document.body); - - expect(mockSetIsOpen).toHaveBeenCalledWith(false); - }); - - it('should not close the wallet when clicking inside', () => { - (useWalletContext as ReturnType).mockReturnValue({ - isOpen: true, - setIsOpen: mockSetIsOpen, - }); - - useAccountMock.mockReturnValue({ address: '123' }); - useBreakpointsMock.mockReturnValue('sm'); - - render( - - - - , - ); - - const walletMenu = screen.getByTestId('ockWalletBottomSheet'); - expect(walletMenu).toBeDefined(); - - fireEvent.click(walletMenu); - - expect(mockSetIsOpen).not.toHaveBeenCalled(); - }); - - it('should not trigger click handler when wallet is closed', () => { - render( - - - - , - ); - - expect(screen.queryByTestId('wallet-dropdown')).toBeNull(); - - fireEvent.click(document.body); - - expect(mockSetIsOpen).not.toHaveBeenCalled(); - }); - - it('should remove event listener on unmount', () => { - const removeEventListenerSpy = vi.spyOn(document, 'removeEventListener'); - - const { unmount } = render( - - - - , - ); - - unmount(); - - expect(removeEventListenerSpy).toHaveBeenCalledWith( - 'click', - expect.any(Function), - ); - }); -}); diff --git a/src/wallet/components/WalletWithMobileDrawer.tsx b/src/wallet/components/WalletWithMobileDrawer.tsx deleted file mode 100644 index b201cb6c36..0000000000 --- a/src/wallet/components/WalletWithMobileDrawer.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { Children, useEffect, useMemo, useRef } from 'react'; -import { findComponent } from '../../internal/utils/findComponent'; -import type { WalletReact } from '../types'; -import { ConnectWallet } from './ConnectWallet'; -import { WalletMenu } from './WalletMenu'; -import { WalletProvider, useWalletContext } from './WalletProvider'; - -const WalletContent = ({ children }: WalletReact) => { - const { isOpen, setIsOpen } = useWalletContext(); - const walletContainerRef = useRef(null); - - const { menu, connect } = useMemo(() => { - const childrenArray = Children.toArray(children); - return { - connect: childrenArray.find(findComponent(ConnectWallet)), - menu: childrenArray.find(findComponent(WalletMenu)), - }; - }, [children]); - - // Handle clicking outside the wallet component to close the dropdown. - useEffect(() => { - const handleClickOutsideComponent = (event: MouseEvent) => { - if ( - walletContainerRef.current && - !walletContainerRef.current.contains(event.target as Node) && - isOpen - ) { - setIsOpen(false); - } - }; - - document.addEventListener('click', handleClickOutsideComponent); - return () => - document.removeEventListener('click', handleClickOutsideComponent); - }, [isOpen, setIsOpen]); - - return ( -
- {connect} - {isOpen && menu} -
- ); -}; - -export const WalletWithMobileDrawer = ({ children }: WalletReact) => { - return ( - - {children} - - ); -}; diff --git a/src/wallet/index.ts b/src/wallet/index.ts index 035217a867..4ad918a33c 100644 --- a/src/wallet/index.ts +++ b/src/wallet/index.ts @@ -2,12 +2,10 @@ export { ConnectWallet } from './components/ConnectWallet'; export { Wallet } from './components/Wallet'; export { WalletDropdown } from './components/WalletDropdown'; -export { WalletMenu } from './components/WalletMenu'; export { WalletBottomSheet } from './components/WalletBottomSheet'; export { WalletDropdownBaseName } from './components/WalletDropdownBaseName'; export { WalletDropdownDisconnect } from './components/WalletDropdownDisconnect'; export { WalletDropdownLink } from './components/WalletDropdownLink'; -export { WalletWithMobileDrawer } from './components/WalletWithMobileDrawer'; export { isValidAAEntrypoint } from './utils/isValidAAEntrypoint'; export { isWalletACoinbaseSmartWallet } from './utils/isWalletACoinbaseSmartWallet'; export type { diff --git a/src/wallet/types.ts b/src/wallet/types.ts index 631af1d129..df4cbf0c3c 100644 --- a/src/wallet/types.ts +++ b/src/wallet/types.ts @@ -114,12 +114,4 @@ export type WalletDropdownLinkReact = { icon?: 'wallet' & ReactNode; rel?: string; target?: string; -}; - -/** - * Note: exported as public Type - */ -export type WalletMenuReact = { - children: React.ReactNode; - className?: string; // Optional className override for top div element -}; +}; \ No newline at end of file