diff --git a/src/wallet/components/WalletDropdownFundLink.test.tsx b/src/wallet/components/WalletDropdownFundLink.test.tsx index c34cc1f5e7..0fc6ae2d1d 100644 --- a/src/wallet/components/WalletDropdownFundLink.test.tsx +++ b/src/wallet/components/WalletDropdownFundLink.test.tsx @@ -1,6 +1,7 @@ import { fireEvent, render, screen } from '@testing-library/react'; import { expect, it, vi } from 'vitest'; import { version } from '../../version'; +import type { WindowSizes } from '../types'; import { WalletDropdownFundLink } from './WalletDropdownFundLink'; const FUNDING_URL = `http://keys.coinbase.com/funding?dappName=&dappUrl=http://localhost:3000/&onchainkit=${version}`; @@ -35,7 +36,7 @@ describe('WalletDropdownFundLink', () => { expect(screen.getByText('test')).toBeInTheDocument(); }); - it('opens a new window when clicked with type="window"', () => { + it('opens a new window when clicked with type="window" (default size medium)', () => { // Mock window.open const mockOpen = vi.fn(); vi.stubGlobal('open', mockOpen); @@ -52,41 +53,61 @@ describe('WalletDropdownFundLink', () => { expect(mockOpen).toHaveBeenCalledWith( expect.stringContaining('http://keys.coinbase.com/funding'), 'Coinbase Fund Wallet', - expect.stringContaining('width=600,height=700'), + expect.stringContaining( + 'width=297,height=371,resizable,scrollbars=yes,status=1,left=364,top=199', + ), ); // Clean up vi.unstubAllGlobals(); }); - const testCases: Array<{ - size: 's' | 'm' | 'l'; - width: number; - height: number; - }> = [ - { size: 's', width: 400, height: 500 }, - { size: 'm', width: 600, height: 700 }, - { size: 'l', width: 800, height: 900 }, - ]; - - for (const { size, width, height } of testCases) { + const testCases: WindowSizes = { + s: { width: '23vw', height: '28.75vw' }, + m: { width: '29vw', height: '36.25vw' }, + l: { width: '35vw', height: '43.75vw' }, + }; + + const minWidth = 280; + const minHeight = 350; + + for (const [size, { width, height }] of Object.entries(testCases)) { it(`opens a new window when clicked with type="window" and windowSize="${size}"`, () => { const mockOpen = vi.fn(); + const screenWidth = 1024; + const screenHeight = 768; + const innerWidth = 1024; + const innerHeight = 768; + vi.stubGlobal('open', mockOpen); - vi.stubGlobal('screen', { width: 1024, height: 768 }); + vi.stubGlobal('screen', { width: screenWidth, height: screenHeight }); - render(); + render( + , + ); const linkElement = screen.getByText('Fund wallet'); fireEvent.click(linkElement); - const expectedLeft = (1024 - width) / 2; - const expectedTop = (768 - height) / 2; + const vwToPx = (vw: string) => + Math.round((Number.parseFloat(vw) / 100) * innerWidth); + + const expectedWidth = Math.max(minWidth, vwToPx(width)); + const expectedHeight = Math.max(minHeight, vwToPx(height)); + const adjustedHeight = Math.min( + expectedHeight, + Math.round(innerHeight * 0.9), + ); + const expectedLeft = Math.round((screenWidth - expectedWidth) / 2); + const expectedTop = Math.round((screenHeight - adjustedHeight) / 2); expect(mockOpen).toHaveBeenCalledWith( expect.stringContaining('http://keys.coinbase.com/funding'), 'Coinbase Fund Wallet', expect.stringContaining( - `width=${width},height=${height},resizable,scrollbars=yes,status=1,left=${expectedLeft},top=${expectedTop}`, + `width=${expectedWidth},height=${adjustedHeight},resizable,scrollbars=yes,status=1,left=${expectedLeft},top=${expectedTop}`, ), ); diff --git a/src/wallet/components/WalletDropdownFundLink.tsx b/src/wallet/components/WalletDropdownFundLink.tsx index bfc3e85dd4..f357375e19 100644 --- a/src/wallet/components/WalletDropdownFundLink.tsx +++ b/src/wallet/components/WalletDropdownFundLink.tsx @@ -26,26 +26,41 @@ export function WalletDropdownFundLink({ const tabName = document.title; const fundingUrl = `http://keys.coinbase.com/funding?dappName=${tabName}&dappUrl=${currentURL}&onchainkit=${version}`; const windowSizes: WindowSizes = { - s: { width: '40vw', height: '50vh' }, - m: { width: '60vw', height: '70vh' }, - l: { width: '80vw', height: '90vh' }, + s: { width: '23vw', height: '28.75vw' }, + m: { width: '29vw', height: '36.25vw' }, + l: { width: '35vw', height: '43.75vw' }, }; const handleClick = (e: React.MouseEvent) => { e.preventDefault(); const { width, height } = windowSizes[windowSize]; - // Convert viewport to pixels - const widthPx = Math.round( - (Number.parseInt(width) / 100) * window.innerWidth, + // Define minimum sizes (in pixels) + const minWidth = 280; + const minHeight = 350; + + // Convert viewport units to pixels + const vwToPx = (vw: number) => (vw / 100) * window.innerWidth; + + const widthPx = Math.max( + minWidth, + Math.round(vwToPx(Number.parseFloat(width))), ); - const heightPx = Math.round( - (Number.parseInt(height) / 100) * window.innerHeight, + const heightPx = Math.max( + minHeight, + Math.round(vwToPx(Number.parseFloat(height))), ); - const left = (window.screen.width - widthPx) / 2; - const top = (window.screen.height - heightPx) / 2; - const windowFeatures = `width=${widthPx},height=${heightPx},resizable,scrollbars=yes,status=1,left=${left},top=${top}`; + // Ensure the width and height don't exceed 90% of the viewport dimensions + const maxWidth = Math.round(window.innerWidth * 0.9); + const maxHeight = Math.round(window.innerHeight * 0.9); + const adjustedWidthPx = Math.min(widthPx, maxWidth); + const adjustedHeightPx = Math.min(heightPx, maxHeight); + + const left = Math.round((window.screen.width - adjustedWidthPx) / 2); + const top = Math.round((window.screen.height - adjustedHeightPx) / 2); + + const windowFeatures = `width=${adjustedWidthPx},height=${adjustedHeightPx},resizable,scrollbars=yes,status=1,left=${left},top=${top}`; window.open(fundingUrl, 'Coinbase Fund Wallet', windowFeatures); };