From c62ca076c1249642c270fcd7f3c5e44d8c195e84 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Thu, 8 Aug 2024 21:19:20 -0700 Subject: [PATCH 01/51] `WalletDropdownFundLink` component --- src/internal/svg/fundWallet.tsx | 17 +++++++ .../WalletDropdownFundLink.test.tsx | 47 +++++++++++++++++++ .../components/WalletDropdownFundLink.tsx | 44 +++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 src/internal/svg/fundWallet.tsx create mode 100644 src/wallet/components/WalletDropdownFundLink.test.tsx create mode 100644 src/wallet/components/WalletDropdownFundLink.tsx diff --git a/src/internal/svg/fundWallet.tsx b/src/internal/svg/fundWallet.tsx new file mode 100644 index 0000000000..91aa26df62 --- /dev/null +++ b/src/internal/svg/fundWallet.tsx @@ -0,0 +1,17 @@ +import { fill } from '../../styles/theme'; + +export const FundWalletSvg = ( + + + +); diff --git a/src/wallet/components/WalletDropdownFundLink.test.tsx b/src/wallet/components/WalletDropdownFundLink.test.tsx new file mode 100644 index 0000000000..f3bdb35854 --- /dev/null +++ b/src/wallet/components/WalletDropdownFundLink.test.tsx @@ -0,0 +1,47 @@ +import { render, screen } from '@testing-library/react'; +import { describe, expect, it } from 'vitest'; +import { WalletDropdownFundLink } from './WalletDropdownFundLink'; + +const FUNDING_URL = + 'http://keys.coinbase.com/funding?dappName=&dappUrl=http://localhost:3000/'; + +describe('WalletDropdownFundLink', () => { + it('renders correctly with default props', () => { + render(); + + const linkElement = screen.getByRole('link'); + expect(linkElement).toBeInTheDocument(); + expect(linkElement).toHaveAttribute('href', FUNDING_URL); + expect(screen.getByText('Deposit Funds')).toBeInTheDocument(); + }); + + it('renders correctly with custom icon element', () => { + const customIcon = ; + render( + + Link Text + + ); + + const linkElement = screen.getByRole('link'); + expect(linkElement).toBeInTheDocument(); + expect(linkElement).toHaveAttribute('href', FUNDING_URL); + expect(screen.getByText('Link Text')).toBeInTheDocument(); + expect(screen.getByLabelText('custom-icon')).toBeInTheDocument(); + }); + + it('renders correctly with target and rel attributes', () => { + render( + + Link Text + + ); + + const linkElement = screen.getByRole('link'); + expect(linkElement).toBeInTheDocument(); + expect(linkElement).toHaveAttribute('href', FUNDING_URL); + expect(linkElement).toHaveAttribute('target', '_blank'); + expect(linkElement).toHaveAttribute('rel', 'noopener noreferrer'); + expect(screen.getByText('Link Text')).toBeInTheDocument(); + }); +}); diff --git a/src/wallet/components/WalletDropdownFundLink.tsx b/src/wallet/components/WalletDropdownFundLink.tsx new file mode 100644 index 0000000000..01deaeb40c --- /dev/null +++ b/src/wallet/components/WalletDropdownFundLink.tsx @@ -0,0 +1,44 @@ +import { isValidElement, useMemo } from 'react'; +import { FundWalletSvg } from '../../internal/svg/fundWallet'; +import { cn, pressable, text } from '../../styles/theme'; +import type { WalletDropdownLinkReact } from '../types'; + +export function WalletDropdownFundLink({ + children, + className, + icon, + rel, + target, +}: WalletDropdownLinkReact) { + const iconSvg = useMemo(() => { + if (icon === undefined) { + return FundWalletSvg; + } + if (isValidElement(icon)) { + return icon; + } + }, [icon]); + + const currentURL = window.location.href; + const tabName = document.title; + + return ( + +
+ {iconSvg} +
+ + {children || 'Deposit Funds'} + +
+ ); +} From 1f8aa0e3d3203cb41a283ea3a9490a9575fbdb8b Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 09:39:10 -0700 Subject: [PATCH 02/51] types --- src/wallet/index.ts | 2 ++ src/wallet/types.ts | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/wallet/index.ts b/src/wallet/index.ts index 6063116126..eec4f9abea 100644 --- a/src/wallet/index.ts +++ b/src/wallet/index.ts @@ -4,6 +4,7 @@ export { Wallet } from './components/Wallet'; export { WalletDropdown } from './components/WalletDropdown'; export { WalletDropdownBaseName } from './components/WalletDropdownBaseName'; export { WalletDropdownDisconnect } from './components/WalletDropdownDisconnect'; +export { WalletDropdownFundLink } from './components/WalletDropdownFundLink'; export { WalletDropdownLink } from './components/WalletDropdownLink'; export { isValidAAEntrypoint } from './utils/isValidAAEntrypoint'; export { isWalletACoinbaseSmartWallet } from './utils/isWalletACoinbaseSmartWallet'; @@ -16,6 +17,7 @@ export type { WalletDropdownBaseNameReact, WalletDropdownDisconnectReact, WalletDropdownLinkReact, + WalletDropdownFundLinkReact, WalletDropdownReact, WalletReact, } from './types'; diff --git a/src/wallet/types.ts b/src/wallet/types.ts index 631a2566f9..24e1b15b42 100644 --- a/src/wallet/types.ts +++ b/src/wallet/types.ts @@ -107,3 +107,17 @@ export type WalletDropdownLinkReact = { rel?: string; target?: string; }; + +/** + * Note: exported as public Type + */ +export type WalletDropdownFundLinkReact = { + className?: string; // Optional className override for the element + href: string; + icon?: ReactNode; + rel?: string; + target?: string; + text?: string; + type?: 'window' | 'tab'; + size?: 's' | 'm' | 'l'; +}; From ae3e8dd69ee62926085aa0e6a406e5789f0c94c2 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 09:39:18 -0700 Subject: [PATCH 03/51] window mode --- .../WalletDropdownFundLink.test.tsx | 48 +++++++++----- .../components/WalletDropdownFundLink.tsx | 64 ++++++++++++++----- 2 files changed, 78 insertions(+), 34 deletions(-) diff --git a/src/wallet/components/WalletDropdownFundLink.test.tsx b/src/wallet/components/WalletDropdownFundLink.test.tsx index f3bdb35854..bab4714aa3 100644 --- a/src/wallet/components/WalletDropdownFundLink.test.tsx +++ b/src/wallet/components/WalletDropdownFundLink.test.tsx @@ -1,5 +1,5 @@ -import { render, screen } from '@testing-library/react'; -import { describe, expect, it } from 'vitest'; +import { render, screen, fireEvent } from '@testing-library/react'; +import { describe, expect, it, vi } from 'vitest'; import { WalletDropdownFundLink } from './WalletDropdownFundLink'; const FUNDING_URL = @@ -17,31 +17,45 @@ describe('WalletDropdownFundLink', () => { it('renders correctly with custom icon element', () => { const customIcon = ; - render( - - Link Text - - ); + render(); const linkElement = screen.getByRole('link'); expect(linkElement).toBeInTheDocument(); expect(linkElement).toHaveAttribute('href', FUNDING_URL); - expect(screen.getByText('Link Text')).toBeInTheDocument(); + expect(screen.getByText('Deposit Funds')).toBeInTheDocument(); expect(screen.getByLabelText('custom-icon')).toBeInTheDocument(); }); - it('renders correctly with target and rel attributes', () => { - render( - - Link Text - - ); + it('renders correctly with custom text', () => { + render(); const linkElement = screen.getByRole('link'); expect(linkElement).toBeInTheDocument(); expect(linkElement).toHaveAttribute('href', FUNDING_URL); - expect(linkElement).toHaveAttribute('target', '_blank'); - expect(linkElement).toHaveAttribute('rel', 'noopener noreferrer'); - expect(screen.getByText('Link Text')).toBeInTheDocument(); + expect(screen.getByText('test')).toBeInTheDocument(); + }); + + it('opens a new window when clicked with type="window"', () => { + // Mock window.open + const mockOpen = vi.fn(); + vi.stubGlobal('open', mockOpen); + + // Mock window.screen + vi.stubGlobal('screen', { width: 1024, height: 768 }); + + render(); + + const linkElement = screen.getByText('Deposit Funds'); + fireEvent.click(linkElement); + + // Check if window.open was called with the correct arguments + expect(mockOpen).toHaveBeenCalledWith( + expect.stringContaining('http://keys.coinbase.com/funding'), + 'Coinbase Fund Wallet', + expect.stringContaining('width=600,height=700'), + ); + + // Clean up + vi.unstubAllGlobals(); }); }); diff --git a/src/wallet/components/WalletDropdownFundLink.tsx b/src/wallet/components/WalletDropdownFundLink.tsx index 01deaeb40c..6c2b2359cc 100644 --- a/src/wallet/components/WalletDropdownFundLink.tsx +++ b/src/wallet/components/WalletDropdownFundLink.tsx @@ -1,15 +1,17 @@ import { isValidElement, useMemo } from 'react'; import { FundWalletSvg } from '../../internal/svg/fundWallet'; -import { cn, pressable, text } from '../../styles/theme'; -import type { WalletDropdownLinkReact } from '../types'; +import { cn, pressable, text as themeText } from '../../styles/theme'; +import type { WalletDropdownFundLinkReact } from '../types'; export function WalletDropdownFundLink({ - children, className, icon, rel, target, -}: WalletDropdownLinkReact) { + text = 'Deposit Funds', + type = 'tab', + size = 'm', +}: WalletDropdownFundLinkReact) { const iconSvg = useMemo(() => { if (icon === undefined) { return FundWalletSvg; @@ -21,24 +23,52 @@ export function WalletDropdownFundLink({ const currentURL = window.location.href; const tabName = document.title; + const windowSizes: Record< + 's' | 'm' | 'l', + { + width: number; + height: number; + } + > = { + s: { width: 400, height: 500 }, + m: { width: 600, height: 700 }, + l: { width: 800, height: 900 }, + }; + + const handleClick = (e: React.MouseEvent) => { + e.preventDefault(); + const url = `http://keys.coinbase.com/funding?dappName=${tabName}&dappUrl=${currentURL}`; + const { width, height } = windowSizes[size]; + const left = (window.screen.width - width) / 2; + const top = (window.screen.height - height) / 2; + const windowFeatures = `width=${width},height=${height},resizable,scrollbars=yes,status=1,left=${left},top=${top}`; + window.open(url, 'Coinbase Fund Wallet', windowFeatures); + }; + + const commonProps = { + className: cn( + pressable.default, + 'relative flex items-center px-4 py-3', + className, + ), + }; + + const linkProps = + type === 'tab' + ? { + ...commonProps, + href: `http://keys.coinbase.com/funding?dappName=${tabName}&dappUrl=${currentURL}`, + target, + rel, + } + : { ...commonProps, onClick: handleClick }; return ( - +
{iconSvg}
- - {children || 'Deposit Funds'} - + {text}
); } From 89112aac59c64d634cf62500c287d95359d7288e Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 09:39:23 -0700 Subject: [PATCH 04/51] docs --- site/docs/pages/wallet/types.mdx | 15 ++ .../wallet/wallet-dropdown-fund-link.mdx | 185 ++++++++++++++++++ site/sidebar.ts | 6 +- 3 files changed, 203 insertions(+), 3 deletions(-) create mode 100644 site/docs/pages/wallet/wallet-dropdown-fund-link.mdx diff --git a/site/docs/pages/wallet/types.mdx b/site/docs/pages/wallet/types.mdx index b8a617f0a8..7445fe133e 100644 --- a/site/docs/pages/wallet/types.mdx +++ b/site/docs/pages/wallet/types.mdx @@ -94,3 +94,18 @@ export type WalletDropdownLinkReact = { target?: string; }; ``` + +## `WalletDropdownFundLinkReact` + +```ts +export type WalletDropdownFundLinkReact = { + className?: string; // Optional className override for the element + href: string; + icon?: ReactNode; + rel?: string; + target?: string; + text?: string; + type?: 'popup' | 'link'; + size?: 's' | 'm' | 'l'; +}; +``` diff --git a/site/docs/pages/wallet/wallet-dropdown-fund-link.mdx b/site/docs/pages/wallet/wallet-dropdown-fund-link.mdx new file mode 100644 index 0000000000..c21328a058 --- /dev/null +++ b/site/docs/pages/wallet/wallet-dropdown-fund-link.mdx @@ -0,0 +1,185 @@ +--- +title: Wallet Components & Utilities · OnchainKit +description: Introduction to Wallet Components & Utilities +--- + +import { + ConnectWallet, + Wallet, + WalletDropdown, + WalletDropdownLink, + WalletDropdownDisconnect, + WalletDropdownFundLink, +} from '../src/wallet'; +import { Address, Avatar, Name, Identity, EthBalance } from '../src/identity'; +import { color } from '@coinbase/onchainkit/theme'; +import AppWithRK from '../../components/AppWithRK'; +import WalletComponents from '../../components/WalletComponents'; + +# `` + +The Wallet Dropdown Fund Link provides an easy way for to access the [Funding](https://keys.coinbase.com/funding) flow for a Coinbase Smart Wallet. + +## Usage + +```tsx +import { + // [!code focus] + ConnectWallet, + Wallet, + WalletDropdown, + WalletDropdownLink, + WalletDropdownDisconnect, + WalletDropdownFundLink, // [!code focus] +} from '@coinbase/onchainkit/wallet'; // [!code focus] +import { + Address, + Avatar, + Name, + Identity, + EthBalance, +} from '@coinbase/onchainkit/identity'; +import { color } from '@coinbase/onchainkit/theme'; + +export function WalletComponents() { + return ( +
+ + + + + + // [!code focus] + + // [!code focus] + + + +
+ + + // [!code focus] + + Wallet + + + + + // [!code focus] +
+ ); +} +``` + + + + + + + + + + + Wallet + + + + + + +### Override text + +You can override component text using the `text` prop. + +```tsx +// omitted for brevity + + + + ... + + + ... + // [!code focus] + + +``` + + + + + + + + + + + + + + +### Open in window + +You can override default link behavior to open the funding flow in a popup window by using the `type` prop. + +```tsx +// omitted for brevity + + + + ... + + + ... + // [!code focus] + + +``` + + + + + + + + + + + + + + +### Customizing the window size + +When using popup mode, you're able to customize the size of the popup window using the `size` prop. Valid values are `s`, `m`, and `l`. + +```tsx +// omitted for brevity + + + + ... + + + ... + // [!code focus] + + +``` + + + + + + + + + + + + + + +## Props + +- [`WalletDropdownFundLinkReact`](/wallet/types#walletdropdownfundlinkreact) diff --git a/site/sidebar.ts b/site/sidebar.ts index 37046d9fa8..b85e867221 100644 --- a/site/sidebar.ts +++ b/site/sidebar.ts @@ -141,7 +141,7 @@ export const sidebar = [ } ], }, - ] + ], }, { text: 'Utilities', @@ -249,7 +249,7 @@ export const sidebar = [ }, ], }, - ] + ], }, { text: 'Types', @@ -287,6 +287,6 @@ export const sidebar = [ text: 'Wallet', link: '/wallet/types', }, - ] + ], }, ] as const satisfies Sidebar; From ec4550349694c06fba1698dc766a2bd38ecfda40 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 09:43:38 -0700 Subject: [PATCH 05/51] lint --- src/internal/svg/fundWallet.tsx | 2 ++ src/wallet/components/WalletDropdownFundLink.test.tsx | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/internal/svg/fundWallet.tsx b/src/internal/svg/fundWallet.tsx index 91aa26df62..a71f805203 100644 --- a/src/internal/svg/fundWallet.tsx +++ b/src/internal/svg/fundWallet.tsx @@ -2,6 +2,8 @@ import { fill } from '../../styles/theme'; export const FundWalletSvg = ( Date: Fri, 9 Aug 2024 09:46:38 -0700 Subject: [PATCH 06/51] fix imports --- .../pages/wallet/wallet-dropdown-fund-link.mdx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/site/docs/pages/wallet/wallet-dropdown-fund-link.mdx b/site/docs/pages/wallet/wallet-dropdown-fund-link.mdx index c21328a058..1738828ef2 100644 --- a/site/docs/pages/wallet/wallet-dropdown-fund-link.mdx +++ b/site/docs/pages/wallet/wallet-dropdown-fund-link.mdx @@ -3,15 +3,21 @@ title: Wallet Components & Utilities · OnchainKit description: Introduction to Wallet Components & Utilities --- -import { +import { ConnectWallet, Wallet, WalletDropdown, + WalletDropdownFundLink WalletDropdownLink, WalletDropdownDisconnect, - WalletDropdownFundLink, -} from '../src/wallet'; -import { Address, Avatar, Name, Identity, EthBalance } from '../src/identity'; +} from '@coinbase/onchainkit/wallet'; +import { + Address, + Avatar, + Name, + Identity, + EthBalance, +} from '@coinbase/onchainkit/identity'; import { color } from '@coinbase/onchainkit/theme'; import AppWithRK from '../../components/AppWithRK'; import WalletComponents from '../../components/WalletComponents'; From 5bb09e7b7e7b8d8d23035f3fcc0bb696d899b7ff Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 09:47:37 -0700 Subject: [PATCH 07/51] organize export --- src/wallet/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/index.ts b/src/wallet/index.ts index eec4f9abea..f26161188d 100644 --- a/src/wallet/index.ts +++ b/src/wallet/index.ts @@ -16,8 +16,8 @@ export type { WalletContextType, WalletDropdownBaseNameReact, WalletDropdownDisconnectReact, - WalletDropdownLinkReact, WalletDropdownFundLinkReact, + WalletDropdownLinkReact, WalletDropdownReact, WalletReact, } from './types'; From 6468a62f26f7911dcc1c9872ef7f0b59d7ee8573 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 10:14:06 -0700 Subject: [PATCH 08/51] changeset --- .changeset/witty-crabs-change.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/witty-crabs-change.md diff --git a/.changeset/witty-crabs-change.md b/.changeset/witty-crabs-change.md new file mode 100644 index 0000000000..49e6bcfe70 --- /dev/null +++ b/.changeset/witty-crabs-change.md @@ -0,0 +1,5 @@ +--- +"@coinbase/onchainkit": patch +--- + +**feat**: WalletDropdownFundLink by @0xAlec #1021 From 7a98d5ac5ac5cbebf85a204018cfe299916d05f3 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 10:22:41 -0700 Subject: [PATCH 09/51] fix build --- site/docs/pages/wallet/wallet-dropdown-fund-link.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/docs/pages/wallet/wallet-dropdown-fund-link.mdx b/site/docs/pages/wallet/wallet-dropdown-fund-link.mdx index 1738828ef2..f4d3006850 100644 --- a/site/docs/pages/wallet/wallet-dropdown-fund-link.mdx +++ b/site/docs/pages/wallet/wallet-dropdown-fund-link.mdx @@ -7,7 +7,7 @@ import { ConnectWallet, Wallet, WalletDropdown, - WalletDropdownFundLink + WalletDropdownFundLink, WalletDropdownLink, WalletDropdownDisconnect, } from '@coinbase/onchainkit/wallet'; From 7d8fd7084c06753d8f98b5eab7da138427a2e445 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 10:23:40 -0700 Subject: [PATCH 10/51] alphabetical export --- src/wallet/types.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/wallet/types.ts b/src/wallet/types.ts index 24e1b15b42..d7f350769b 100644 --- a/src/wallet/types.ts +++ b/src/wallet/types.ts @@ -99,25 +99,25 @@ export type WalletDropdownDisconnectReact = { /** * Note: exported as public Type */ -export type WalletDropdownLinkReact = { - children: string; +export type WalletDropdownFundLinkReact = { className?: string; // Optional className override for the element href: string; - icon?: 'wallet' & ReactNode; + icon?: ReactNode; rel?: string; target?: string; + text?: string; + type?: 'window' | 'tab'; + size?: 's' | 'm' | 'l'; }; /** * Note: exported as public Type */ -export type WalletDropdownFundLinkReact = { +export type WalletDropdownLinkReact = { + children: string; className?: string; // Optional className override for the element href: string; - icon?: ReactNode; + icon?: 'wallet' & ReactNode; rel?: string; target?: string; - text?: string; - type?: 'window' | 'tab'; - size?: 's' | 'm' | 'l'; -}; +}; \ No newline at end of file From c80f4b4e27c695d10b5a1ffdb5943bdc77eebffc Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 11:07:43 -0700 Subject: [PATCH 11/51] format --- src/wallet/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/types.ts b/src/wallet/types.ts index d7f350769b..71d0a8171b 100644 --- a/src/wallet/types.ts +++ b/src/wallet/types.ts @@ -120,4 +120,4 @@ export type WalletDropdownLinkReact = { icon?: 'wallet' & ReactNode; rel?: string; target?: string; -}; \ No newline at end of file +}; From bff46b6e2bcd281745f465d84a02f728e25f5f75 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 11:10:49 -0700 Subject: [PATCH 12/51] cleanup --- site/docs/pages/wallet/wallet-dropdown-fund-link.mdx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/site/docs/pages/wallet/wallet-dropdown-fund-link.mdx b/site/docs/pages/wallet/wallet-dropdown-fund-link.mdx index f4d3006850..8a363ace8c 100644 --- a/site/docs/pages/wallet/wallet-dropdown-fund-link.mdx +++ b/site/docs/pages/wallet/wallet-dropdown-fund-link.mdx @@ -30,7 +30,6 @@ The Wallet Dropdown Fund Link provides an easy way for to access the [Funding](h ```tsx import { - // [!code focus] ConnectWallet, Wallet, WalletDropdown, @@ -55,13 +54,11 @@ export function WalletComponents() { - // [!code focus] - // [!code focus] -
+
// [!code focus] @@ -71,7 +68,6 @@ export function WalletComponents() {
- // [!code focus] ); } From 7495d9285c83887f719e06c791732d46ea2cb5ab Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 11:21:08 -0700 Subject: [PATCH 13/51] update prop names --- site/docs/pages/wallet/wallet-dropdown-fund-link.mdx | 12 ++++++------ src/wallet/components/WalletDropdownFundLink.tsx | 8 ++++---- src/wallet/types.ts | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/site/docs/pages/wallet/wallet-dropdown-fund-link.mdx b/site/docs/pages/wallet/wallet-dropdown-fund-link.mdx index 8a363ace8c..9d11481168 100644 --- a/site/docs/pages/wallet/wallet-dropdown-fund-link.mdx +++ b/site/docs/pages/wallet/wallet-dropdown-fund-link.mdx @@ -122,7 +122,7 @@ You can override component text using the `text` prop. ### Open in window -You can override default link behavior to open the funding flow in a popup window by using the `type` prop. +You can override default link behavior to open the funding flow in a popup window by using the `openIn` prop. ```tsx // omitted for brevity @@ -133,7 +133,7 @@ You can override default link behavior to open the funding flow in a popup windo ... - // [!code focus] + // [!code focus] ``` @@ -145,7 +145,7 @@ You can override default link behavior to open the funding flow in a popup windo - + @@ -153,7 +153,7 @@ You can override default link behavior to open the funding flow in a popup windo ### Customizing the window size -When using popup mode, you're able to customize the size of the popup window using the `size` prop. Valid values are `s`, `m`, and `l`. +When using popup mode, you're able to customize the size of the popup window using the `windowSize` prop. Valid values are `s`, `m`, and `l`. ```tsx // omitted for brevity @@ -164,7 +164,7 @@ When using popup mode, you're able to customize the size of the popup window usi ... - // [!code focus] + // [!code focus] ``` @@ -176,7 +176,7 @@ When using popup mode, you're able to customize the size of the popup window usi - + diff --git a/src/wallet/components/WalletDropdownFundLink.tsx b/src/wallet/components/WalletDropdownFundLink.tsx index 6c2b2359cc..3fbb333c40 100644 --- a/src/wallet/components/WalletDropdownFundLink.tsx +++ b/src/wallet/components/WalletDropdownFundLink.tsx @@ -7,10 +7,10 @@ export function WalletDropdownFundLink({ className, icon, rel, + openIn = 'tab', target, text = 'Deposit Funds', - type = 'tab', - size = 'm', + windowSize = 'm', }: WalletDropdownFundLinkReact) { const iconSvg = useMemo(() => { if (icon === undefined) { @@ -38,7 +38,7 @@ export function WalletDropdownFundLink({ const handleClick = (e: React.MouseEvent) => { e.preventDefault(); const url = `http://keys.coinbase.com/funding?dappName=${tabName}&dappUrl=${currentURL}`; - const { width, height } = windowSizes[size]; + const { width, height } = windowSizes[windowSize]; const left = (window.screen.width - width) / 2; const top = (window.screen.height - height) / 2; const windowFeatures = `width=${width},height=${height},resizable,scrollbars=yes,status=1,left=${left},top=${top}`; @@ -54,7 +54,7 @@ export function WalletDropdownFundLink({ }; const linkProps = - type === 'tab' + openIn === 'tab' ? { ...commonProps, href: `http://keys.coinbase.com/funding?dappName=${tabName}&dappUrl=${currentURL}`, diff --git a/src/wallet/types.ts b/src/wallet/types.ts index 71d0a8171b..3ce5706c78 100644 --- a/src/wallet/types.ts +++ b/src/wallet/types.ts @@ -104,10 +104,10 @@ export type WalletDropdownFundLinkReact = { href: string; icon?: ReactNode; rel?: string; + openIn?: 'window' | 'tab'; target?: string; text?: string; - type?: 'window' | 'tab'; - size?: 's' | 'm' | 'l'; + windowSize?: 's' | 'm' | 'l'; }; /** From a8dc2241d9cf32e41dfce5f136f3f094e17d0d83 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 11:35:42 -0700 Subject: [PATCH 14/51] add test for `windowSize` --- .../WalletDropdownFundLink.test.tsx | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/wallet/components/WalletDropdownFundLink.test.tsx b/src/wallet/components/WalletDropdownFundLink.test.tsx index 55bc7fe0c4..11b77167b9 100644 --- a/src/wallet/components/WalletDropdownFundLink.test.tsx +++ b/src/wallet/components/WalletDropdownFundLink.test.tsx @@ -43,7 +43,7 @@ describe('WalletDropdownFundLink', () => { // Mock window.screen vi.stubGlobal('screen', { width: 1024, height: 768 }); - render(); + render(); const linkElement = screen.getByText('Deposit Funds'); fireEvent.click(linkElement); @@ -58,4 +58,41 @@ describe('WalletDropdownFundLink', () => { // 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 }, + ]; + + testCases.forEach(({ size, width, height }) => { + it(`opens a new window when clicked with type="window" and windowSize="${size}"`, () => { + const mockOpen = vi.fn(); + vi.stubGlobal('open', mockOpen); + vi.stubGlobal('open', mockOpen); + vi.stubGlobal('screen', { width: 1024, height: 768 }); + + render(); + + const linkElement = screen.getByText('Deposit Funds'); + fireEvent.click(linkElement); + + const expectedLeft = (1024 - width) / 2; + const expectedTop = (768 - height) / 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}`, + ), + ); + + vi.unstubAllGlobals(); + vi.clearAllMocks(); + }); + }); }); From 48a926fffd9808715bbcb73cdbb63f8fe3d8bb7d Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 12:08:03 -0700 Subject: [PATCH 15/51] don't use prop destructuring --- .../components/WalletDropdownFundLink.tsx | 47 +++++++++++-------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/src/wallet/components/WalletDropdownFundLink.tsx b/src/wallet/components/WalletDropdownFundLink.tsx index 3fbb333c40..01bb7fb940 100644 --- a/src/wallet/components/WalletDropdownFundLink.tsx +++ b/src/wallet/components/WalletDropdownFundLink.tsx @@ -45,30 +45,37 @@ export function WalletDropdownFundLink({ window.open(url, 'Coinbase Fund Wallet', windowFeatures); }; - const commonProps = { - className: cn( - pressable.default, - 'relative flex items-center px-4 py-3', - className, - ), - }; - - const linkProps = - openIn === 'tab' - ? { - ...commonProps, - href: `http://keys.coinbase.com/funding?dappName=${tabName}&dappUrl=${currentURL}`, - target, - rel, - } - : { ...commonProps, onClick: handleClick }; + const commonClassName = cn( + pressable.default, + 'relative flex items-center px-4 py-3', + className + ); - return ( - + const linkContent = ( + <>
{iconSvg}
{text} - + ); + + if (openIn === 'tab') { + return ( + + {linkContent} + + ); + } else { + return ( + + {linkContent} + + ); + } } From dd771bfb0738fb9c479d0be3a490a34e7c8a18fc Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 12:14:57 -0700 Subject: [PATCH 16/51] lint and format --- .../components/WalletDropdownFundLink.test.tsx | 5 ++--- src/wallet/components/WalletDropdownFundLink.tsx | 13 ++++++------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/wallet/components/WalletDropdownFundLink.test.tsx b/src/wallet/components/WalletDropdownFundLink.test.tsx index 11b77167b9..2551070d8f 100644 --- a/src/wallet/components/WalletDropdownFundLink.test.tsx +++ b/src/wallet/components/WalletDropdownFundLink.test.tsx @@ -69,11 +69,10 @@ describe('WalletDropdownFundLink', () => { { size: 'l', width: 800, height: 900 }, ]; - testCases.forEach(({ size, width, height }) => { + for (const { size, width, height } of testCases) { it(`opens a new window when clicked with type="window" and windowSize="${size}"`, () => { const mockOpen = vi.fn(); vi.stubGlobal('open', mockOpen); - vi.stubGlobal('open', mockOpen); vi.stubGlobal('screen', { width: 1024, height: 768 }); render(); @@ -94,5 +93,5 @@ describe('WalletDropdownFundLink', () => { vi.unstubAllGlobals(); vi.clearAllMocks(); }); - }); + } }); diff --git a/src/wallet/components/WalletDropdownFundLink.tsx b/src/wallet/components/WalletDropdownFundLink.tsx index 01bb7fb940..c37ca5bac7 100644 --- a/src/wallet/components/WalletDropdownFundLink.tsx +++ b/src/wallet/components/WalletDropdownFundLink.tsx @@ -48,7 +48,7 @@ export function WalletDropdownFundLink({ const commonClassName = cn( pressable.default, 'relative flex items-center px-4 py-3', - className + className, ); const linkContent = ( @@ -71,11 +71,10 @@ export function WalletDropdownFundLink({ {linkContent} ); - } else { - return ( - - {linkContent} - - ); } + return ( + + ); } From 3cbe66f9c87213ebd861554183f9fcbcd0cf39e0 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 12:19:30 -0700 Subject: [PATCH 17/51] organize and add comments --- site/docs/pages/wallet/types.mdx | 24 ++++++++++++------------ src/wallet/types.ts | 8 ++++---- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/site/docs/pages/wallet/types.mdx b/site/docs/pages/wallet/types.mdx index 7445fe133e..9b0afaa487 100644 --- a/site/docs/pages/wallet/types.mdx +++ b/site/docs/pages/wallet/types.mdx @@ -82,30 +82,30 @@ export type WalletDropdownDisconnectReact = { }; ``` -## `WalletDropdownLinkReact` +## `WalletDropdownFundLinkReact` ```ts -export type WalletDropdownLinkReact = { - children: string; +export type WalletDropdownFundLinkReact = { className?: string; // Optional className override for the element href: string; - icon?: 'wallet' & ReactNode; + icon?: ReactNode; rel?: string; - target?: string; + openIn?: 'window' | 'tab'; // Whether to open the funding flow in a tab or a window + target?: string; // Where to open the target if `openIn` is set to tab + text?: string; // Optional text override + windowSize?: 's' | 'm' | 'l'; // Size of the popup window if `openIn` is set to window }; ``` -## `WalletDropdownFundLinkReact` +## `WalletDropdownLinkReact` ```ts -export type WalletDropdownFundLinkReact = { +export type WalletDropdownLinkReact = { + children: string; className?: string; // Optional className override for the element href: string; - icon?: ReactNode; + icon?: 'wallet' & ReactNode; rel?: string; target?: string; - text?: string; - type?: 'popup' | 'link'; - size?: 's' | 'm' | 'l'; }; -``` +``` \ No newline at end of file diff --git a/src/wallet/types.ts b/src/wallet/types.ts index 3ce5706c78..bf8d1a6ba4 100644 --- a/src/wallet/types.ts +++ b/src/wallet/types.ts @@ -104,10 +104,10 @@ export type WalletDropdownFundLinkReact = { href: string; icon?: ReactNode; rel?: string; - openIn?: 'window' | 'tab'; - target?: string; - text?: string; - windowSize?: 's' | 'm' | 'l'; + openIn?: 'window' | 'tab'; // Whether to open the funding flow in a tab or a window + target?: string; // Where to open the target if `openIn` is set to tab + text?: string; // Optional text override + windowSize?: 's' | 'm' | 'l'; // Size of the popup window if `openIn` is set to window }; /** From 3b5a0797bcf70de7c1ca04a490076f0746f53939 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 12:19:54 -0700 Subject: [PATCH 18/51] Update witty-crabs-change.md --- .changeset/witty-crabs-change.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/witty-crabs-change.md b/.changeset/witty-crabs-change.md index 49e6bcfe70..0400391d4b 100644 --- a/.changeset/witty-crabs-change.md +++ b/.changeset/witty-crabs-change.md @@ -2,4 +2,4 @@ "@coinbase/onchainkit": patch --- -**feat**: WalletDropdownFundLink by @0xAlec #1021 +**feat**: `WalletDropdownFundLink` - add a wallet dropdown component for the keys.coinbase.com funding flow by @0xAlec #1021 From 83b0cc3ff58f70cc1760afde0d6db5ae7907008a Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 13:47:04 -0700 Subject: [PATCH 19/51] remove component docs --- .../wallet/wallet-dropdown-fund-link.mdx | 187 ------------------ 1 file changed, 187 deletions(-) delete mode 100644 site/docs/pages/wallet/wallet-dropdown-fund-link.mdx diff --git a/site/docs/pages/wallet/wallet-dropdown-fund-link.mdx b/site/docs/pages/wallet/wallet-dropdown-fund-link.mdx deleted file mode 100644 index 9d11481168..0000000000 --- a/site/docs/pages/wallet/wallet-dropdown-fund-link.mdx +++ /dev/null @@ -1,187 +0,0 @@ ---- -title: Wallet Components & Utilities · OnchainKit -description: Introduction to Wallet Components & Utilities ---- - -import { - ConnectWallet, - Wallet, - WalletDropdown, - WalletDropdownFundLink, - WalletDropdownLink, - WalletDropdownDisconnect, -} from '@coinbase/onchainkit/wallet'; -import { - Address, - Avatar, - Name, - Identity, - EthBalance, -} from '@coinbase/onchainkit/identity'; -import { color } from '@coinbase/onchainkit/theme'; -import AppWithRK from '../../components/AppWithRK'; -import WalletComponents from '../../components/WalletComponents'; - -# `` - -The Wallet Dropdown Fund Link provides an easy way for to access the [Funding](https://keys.coinbase.com/funding) flow for a Coinbase Smart Wallet. - -## Usage - -```tsx -import { - ConnectWallet, - Wallet, - WalletDropdown, - WalletDropdownLink, - WalletDropdownDisconnect, - WalletDropdownFundLink, // [!code focus] -} from '@coinbase/onchainkit/wallet'; // [!code focus] -import { - Address, - Avatar, - Name, - Identity, - EthBalance, -} from '@coinbase/onchainkit/identity'; -import { color } from '@coinbase/onchainkit/theme'; - -export function WalletComponents() { - return ( -
- - - - - - - - - -
- - - // [!code focus] - - Wallet - - - - -
- ); -} -``` - - - - - - - - - - - Wallet - - - - - - -### Override text - -You can override component text using the `text` prop. - -```tsx -// omitted for brevity - - - - ... - - - ... - // [!code focus] - - -``` - - - - - - - - - - - - - - -### Open in window - -You can override default link behavior to open the funding flow in a popup window by using the `openIn` prop. - -```tsx -// omitted for brevity - - - - ... - - - ... - // [!code focus] - - -``` - - - - - - - - - - - - - - -### Customizing the window size - -When using popup mode, you're able to customize the size of the popup window using the `windowSize` prop. Valid values are `s`, `m`, and `l`. - -```tsx -// omitted for brevity - - - - ... - - - ... - // [!code focus] - - -``` - - - - - - - - - - - - - - -## Props - -- [`WalletDropdownFundLinkReact`](/wallet/types#walletdropdownfundlinkreact) From 06ada067b4b683a5dc2e2ba81146c86ce6be3ff5 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 13:48:01 -0700 Subject: [PATCH 20/51] add `onchainkit=version` to params --- src/wallet/components/WalletDropdownFundLink.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wallet/components/WalletDropdownFundLink.tsx b/src/wallet/components/WalletDropdownFundLink.tsx index c37ca5bac7..a0fb4bece6 100644 --- a/src/wallet/components/WalletDropdownFundLink.tsx +++ b/src/wallet/components/WalletDropdownFundLink.tsx @@ -1,6 +1,7 @@ import { isValidElement, useMemo } from 'react'; import { FundWalletSvg } from '../../internal/svg/fundWallet'; import { cn, pressable, text as themeText } from '../../styles/theme'; +import { version } from '../../version'; import type { WalletDropdownFundLinkReact } from '../types'; export function WalletDropdownFundLink({ @@ -37,7 +38,7 @@ export function WalletDropdownFundLink({ const handleClick = (e: React.MouseEvent) => { e.preventDefault(); - const url = `http://keys.coinbase.com/funding?dappName=${tabName}&dappUrl=${currentURL}`; + const url = `http://keys.coinbase.com/funding?dappName=${tabName}&dappUrl=${currentURL}&onchainkit=${version}`; const { width, height } = windowSizes[windowSize]; const left = (window.screen.width - width) / 2; const top = (window.screen.height - height) / 2; From 7e0f3936b1ae1da57197cfd04b455f640e0dc440 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 13:48:27 -0700 Subject: [PATCH 21/51] `Fund Wallet` default copy --- src/wallet/components/WalletDropdownFundLink.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/components/WalletDropdownFundLink.tsx b/src/wallet/components/WalletDropdownFundLink.tsx index a0fb4bece6..0a0d8d8efa 100644 --- a/src/wallet/components/WalletDropdownFundLink.tsx +++ b/src/wallet/components/WalletDropdownFundLink.tsx @@ -10,7 +10,7 @@ export function WalletDropdownFundLink({ rel, openIn = 'tab', target, - text = 'Deposit Funds', + text = 'Fund Wallet', windowSize = 'm', }: WalletDropdownFundLinkReact) { const iconSvg = useMemo(() => { From d726dffdb6eabf78839b769615dc50828974c7db Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 13:51:58 -0700 Subject: [PATCH 22/51] format --- site/sidebar.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/site/sidebar.ts b/site/sidebar.ts index b85e867221..37046d9fa8 100644 --- a/site/sidebar.ts +++ b/site/sidebar.ts @@ -141,7 +141,7 @@ export const sidebar = [ } ], }, - ], + ] }, { text: 'Utilities', @@ -249,7 +249,7 @@ export const sidebar = [ }, ], }, - ], + ] }, { text: 'Types', @@ -287,6 +287,6 @@ export const sidebar = [ text: 'Wallet', link: '/wallet/types', }, - ], + ] }, ] as const satisfies Sidebar; From ad0127bcfccd55701d7dd52cc7dffabf1779eb6f Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 13:52:29 -0700 Subject: [PATCH 23/51] add newline --- site/docs/pages/wallet/types.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/docs/pages/wallet/types.mdx b/site/docs/pages/wallet/types.mdx index 9b0afaa487..f0322fbb6d 100644 --- a/site/docs/pages/wallet/types.mdx +++ b/site/docs/pages/wallet/types.mdx @@ -108,4 +108,4 @@ export type WalletDropdownLinkReact = { rel?: string; target?: string; }; -``` \ No newline at end of file +``` From 4252671d06951c10499b032d3262c6516bc8f42c Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 13:56:15 -0700 Subject: [PATCH 24/51] fix tests --- src/wallet/components/WalletDropdownFundLink.test.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wallet/components/WalletDropdownFundLink.test.tsx b/src/wallet/components/WalletDropdownFundLink.test.tsx index 2551070d8f..f8e3792b5e 100644 --- a/src/wallet/components/WalletDropdownFundLink.test.tsx +++ b/src/wallet/components/WalletDropdownFundLink.test.tsx @@ -12,7 +12,7 @@ describe('WalletDropdownFundLink', () => { const linkElement = screen.getByRole('link'); expect(linkElement).toBeInTheDocument(); expect(linkElement).toHaveAttribute('href', FUNDING_URL); - expect(screen.getByText('Deposit Funds')).toBeInTheDocument(); + expect(screen.getByText('Fund Wallet')).toBeInTheDocument(); }); it('renders correctly with custom icon element', () => { @@ -22,7 +22,7 @@ describe('WalletDropdownFundLink', () => { const linkElement = screen.getByRole('link'); expect(linkElement).toBeInTheDocument(); expect(linkElement).toHaveAttribute('href', FUNDING_URL); - expect(screen.getByText('Deposit Funds')).toBeInTheDocument(); + expect(screen.getByText('Fund Wallet')).toBeInTheDocument(); expect(screen.getByLabelText('custom-icon')).toBeInTheDocument(); }); @@ -45,7 +45,7 @@ describe('WalletDropdownFundLink', () => { render(); - const linkElement = screen.getByText('Deposit Funds'); + const linkElement = screen.getByText('Fund Wallet'); fireEvent.click(linkElement); // Check if window.open was called with the correct arguments @@ -77,7 +77,7 @@ describe('WalletDropdownFundLink', () => { render(); - const linkElement = screen.getByText('Deposit Funds'); + const linkElement = screen.getByText('Fund Wallet'); fireEvent.click(linkElement); const expectedLeft = (1024 - width) / 2; From 96597ca5c2e2ddc0018c7122501479d5970b705b Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 14:03:17 -0700 Subject: [PATCH 25/51] sentence case --- .../components/WalletDropdownFundLink.test.tsx | 12 ++++++------ src/wallet/components/WalletDropdownFundLink.tsx | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/wallet/components/WalletDropdownFundLink.test.tsx b/src/wallet/components/WalletDropdownFundLink.test.tsx index f8e3792b5e..0f453a3875 100644 --- a/src/wallet/components/WalletDropdownFundLink.test.tsx +++ b/src/wallet/components/WalletDropdownFundLink.test.tsx @@ -12,7 +12,7 @@ describe('WalletDropdownFundLink', () => { const linkElement = screen.getByRole('link'); expect(linkElement).toBeInTheDocument(); expect(linkElement).toHaveAttribute('href', FUNDING_URL); - expect(screen.getByText('Fund Wallet')).toBeInTheDocument(); + expect(screen.getByText('Fund wallet')).toBeInTheDocument(); }); it('renders correctly with custom icon element', () => { @@ -22,7 +22,7 @@ describe('WalletDropdownFundLink', () => { const linkElement = screen.getByRole('link'); expect(linkElement).toBeInTheDocument(); expect(linkElement).toHaveAttribute('href', FUNDING_URL); - expect(screen.getByText('Fund Wallet')).toBeInTheDocument(); + expect(screen.getByText('Fund wallet')).toBeInTheDocument(); expect(screen.getByLabelText('custom-icon')).toBeInTheDocument(); }); @@ -45,13 +45,13 @@ describe('WalletDropdownFundLink', () => { render(); - const linkElement = screen.getByText('Fund Wallet'); + const linkElement = screen.getByText('Fund wallet'); fireEvent.click(linkElement); // Check if window.open was called with the correct arguments expect(mockOpen).toHaveBeenCalledWith( expect.stringContaining('http://keys.coinbase.com/funding'), - 'Coinbase Fund Wallet', + 'Coinbase Fund wallet', expect.stringContaining('width=600,height=700'), ); @@ -77,14 +77,14 @@ describe('WalletDropdownFundLink', () => { render(); - const linkElement = screen.getByText('Fund Wallet'); + const linkElement = screen.getByText('Fund wallet'); fireEvent.click(linkElement); const expectedLeft = (1024 - width) / 2; const expectedTop = (768 - height) / 2; expect(mockOpen).toHaveBeenCalledWith( expect.stringContaining('http://keys.coinbase.com/funding'), - 'Coinbase Fund Wallet', + 'Coinbase Fund wallet', expect.stringContaining( `width=${width},height=${height},resizable,scrollbars=yes,status=1,left=${expectedLeft},top=${expectedTop}`, ), diff --git a/src/wallet/components/WalletDropdownFundLink.tsx b/src/wallet/components/WalletDropdownFundLink.tsx index 0a0d8d8efa..14ed43a81d 100644 --- a/src/wallet/components/WalletDropdownFundLink.tsx +++ b/src/wallet/components/WalletDropdownFundLink.tsx @@ -10,7 +10,7 @@ export function WalletDropdownFundLink({ rel, openIn = 'tab', target, - text = 'Fund Wallet', + text = 'Fund wallet', windowSize = 'm', }: WalletDropdownFundLinkReact) { const iconSvg = useMemo(() => { From 48a25bc0935361f46d6c23773e094ad442b5b17c Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 14:07:56 -0700 Subject: [PATCH 26/51] fix --- src/wallet/components/WalletDropdownFundLink.test.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/components/WalletDropdownFundLink.test.tsx b/src/wallet/components/WalletDropdownFundLink.test.tsx index 0f453a3875..30f703a54f 100644 --- a/src/wallet/components/WalletDropdownFundLink.test.tsx +++ b/src/wallet/components/WalletDropdownFundLink.test.tsx @@ -51,7 +51,7 @@ describe('WalletDropdownFundLink', () => { // Check if window.open was called with the correct arguments expect(mockOpen).toHaveBeenCalledWith( expect.stringContaining('http://keys.coinbase.com/funding'), - 'Coinbase Fund wallet', + 'Coinbase Fund Wallet', expect.stringContaining('width=600,height=700'), ); @@ -84,7 +84,7 @@ describe('WalletDropdownFundLink', () => { const expectedTop = (768 - height) / 2; expect(mockOpen).toHaveBeenCalledWith( expect.stringContaining('http://keys.coinbase.com/funding'), - 'Coinbase Fund wallet', + 'Coinbase Fund Wallet', expect.stringContaining( `width=${width},height=${height},resizable,scrollbars=yes,status=1,left=${expectedLeft},top=${expectedTop}`, ), From c74b3a1029d84393bd817408442a0e18284de807 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 14:18:45 -0700 Subject: [PATCH 27/51] add `fundingUrl` --- src/wallet/components/WalletDropdownFundLink.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wallet/components/WalletDropdownFundLink.tsx b/src/wallet/components/WalletDropdownFundLink.tsx index 14ed43a81d..04311f45b8 100644 --- a/src/wallet/components/WalletDropdownFundLink.tsx +++ b/src/wallet/components/WalletDropdownFundLink.tsx @@ -21,9 +21,10 @@ export function WalletDropdownFundLink({ return icon; } }, [icon]); - + const currentURL = window.location.href; const tabName = document.title; + const fundingUrl = `http://keys.coinbase.com/funding?dappName=${tabName}&dappUrl=${currentURL}&onchainkit=${version}`; const windowSizes: Record< 's' | 'm' | 'l', { @@ -38,12 +39,11 @@ export function WalletDropdownFundLink({ const handleClick = (e: React.MouseEvent) => { e.preventDefault(); - const url = `http://keys.coinbase.com/funding?dappName=${tabName}&dappUrl=${currentURL}&onchainkit=${version}`; const { width, height } = windowSizes[windowSize]; const left = (window.screen.width - width) / 2; const top = (window.screen.height - height) / 2; const windowFeatures = `width=${width},height=${height},resizable,scrollbars=yes,status=1,left=${left},top=${top}`; - window.open(url, 'Coinbase Fund Wallet', windowFeatures); + window.open(fundingUrl, 'Coinbase Fund Wallet', windowFeatures); }; const commonClassName = cn( @@ -65,7 +65,7 @@ export function WalletDropdownFundLink({ return ( From 99816a0fcd359e8fdcc016f9d5187d935ea9a3e5 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 14:22:00 -0700 Subject: [PATCH 28/51] format --- src/wallet/components/WalletDropdownFundLink.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/components/WalletDropdownFundLink.tsx b/src/wallet/components/WalletDropdownFundLink.tsx index 04311f45b8..0129812adc 100644 --- a/src/wallet/components/WalletDropdownFundLink.tsx +++ b/src/wallet/components/WalletDropdownFundLink.tsx @@ -21,7 +21,7 @@ export function WalletDropdownFundLink({ return icon; } }, [icon]); - + const currentURL = window.location.href; const tabName = document.title; const fundingUrl = `http://keys.coinbase.com/funding?dappName=${tabName}&dappUrl=${currentURL}&onchainkit=${version}`; From 5325599f996b9d0a8b0b187b53897b462ef86627 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 14:35:43 -0700 Subject: [PATCH 29/51] fix test --- src/wallet/components/WalletDropdownFundLink.test.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wallet/components/WalletDropdownFundLink.test.tsx b/src/wallet/components/WalletDropdownFundLink.test.tsx index 30f703a54f..c20e3e6503 100644 --- a/src/wallet/components/WalletDropdownFundLink.test.tsx +++ b/src/wallet/components/WalletDropdownFundLink.test.tsx @@ -1,9 +1,9 @@ import { fireEvent, render, screen } from '@testing-library/react'; -import { describe, expect, it, vi } from 'vitest'; +import { expect, it, vi } from 'vitest'; +import { version } from '../../version'; import { WalletDropdownFundLink } from './WalletDropdownFundLink'; -const FUNDING_URL = - 'http://keys.coinbase.com/funding?dappName=&dappUrl=http://localhost:3000/'; +const FUNDING_URL = `http://keys.coinbase.com/funding?dappName=&dappUrl=http://localhost:3000/onchainkit=${version}`; describe('WalletDropdownFundLink', () => { it('renders correctly with default props', () => { From 7387e2d9f29c1205ce60c2903467930f52464223 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 14:41:26 -0700 Subject: [PATCH 30/51] final --- src/wallet/components/WalletDropdownFundLink.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/components/WalletDropdownFundLink.test.tsx b/src/wallet/components/WalletDropdownFundLink.test.tsx index c20e3e6503..c34cc1f5e7 100644 --- a/src/wallet/components/WalletDropdownFundLink.test.tsx +++ b/src/wallet/components/WalletDropdownFundLink.test.tsx @@ -3,7 +3,7 @@ import { expect, it, vi } from 'vitest'; import { version } from '../../version'; import { WalletDropdownFundLink } from './WalletDropdownFundLink'; -const FUNDING_URL = `http://keys.coinbase.com/funding?dappName=&dappUrl=http://localhost:3000/onchainkit=${version}`; +const FUNDING_URL = `http://keys.coinbase.com/funding?dappName=&dappUrl=http://localhost:3000/&onchainkit=${version}`; describe('WalletDropdownFundLink', () => { it('renders correctly with default props', () => { From 2efd1d7c5331f5b9f32335d92c294dc5f269fe83 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 15:30:53 -0700 Subject: [PATCH 31/51] add windowsizes --- src/wallet/types.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/wallet/types.ts b/src/wallet/types.ts index bf8d1a6ba4..b5ae464d3a 100644 --- a/src/wallet/types.ts +++ b/src/wallet/types.ts @@ -121,3 +121,11 @@ export type WalletDropdownLinkReact = { rel?: string; target?: string; }; + +export type WindowSizes = Record< + 's' | 'm' | 'l', + { + width: string; + height: string; + } +>; From 71ac9f586a1ee484601f381e0c2f4fea134e8875 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 15:30:59 -0700 Subject: [PATCH 32/51] use viewports --- .../WalletDropdownFundLink.test.tsx | 57 +++++++++++++------ .../components/WalletDropdownFundLink.tsx | 46 ++++++++++----- 2 files changed, 71 insertions(+), 32 deletions(-) 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 0129812adc..f357375e19 100644 --- a/src/wallet/components/WalletDropdownFundLink.tsx +++ b/src/wallet/components/WalletDropdownFundLink.tsx @@ -2,7 +2,7 @@ import { isValidElement, useMemo } from 'react'; import { FundWalletSvg } from '../../internal/svg/fundWallet'; import { cn, pressable, text as themeText } from '../../styles/theme'; import { version } from '../../version'; -import type { WalletDropdownFundLinkReact } from '../types'; +import type { WalletDropdownFundLinkReact, WindowSizes } from '../types'; export function WalletDropdownFundLink({ className, @@ -25,24 +25,42 @@ export function WalletDropdownFundLink({ const currentURL = window.location.href; const tabName = document.title; const fundingUrl = `http://keys.coinbase.com/funding?dappName=${tabName}&dappUrl=${currentURL}&onchainkit=${version}`; - const windowSizes: Record< - 's' | 'm' | 'l', - { - width: number; - height: number; - } - > = { - s: { width: 400, height: 500 }, - m: { width: 600, height: 700 }, - l: { width: 800, height: 900 }, + const windowSizes: WindowSizes = { + 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]; - const left = (window.screen.width - width) / 2; - const top = (window.screen.height - height) / 2; - const windowFeatures = `width=${width},height=${height},resizable,scrollbars=yes,status=1,left=${left},top=${top}`; + + // 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.max( + minHeight, + Math.round(vwToPx(Number.parseFloat(height))), + ); + + // 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); }; From 320004aef35a4ce4d41b238aacb10bfecb345ee4 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 15:36:13 -0700 Subject: [PATCH 33/51] `getWindowDimensions` --- .../components/WalletDropdownFundLink.tsx | 38 +++----------- src/wallet/utils/getWindowDimensions.test.ts | 52 +++++++++++++++++++ src/wallet/utils/getWindowDimensions.ts | 35 +++++++++++++ 3 files changed, 93 insertions(+), 32 deletions(-) create mode 100644 src/wallet/utils/getWindowDimensions.test.ts create mode 100644 src/wallet/utils/getWindowDimensions.ts diff --git a/src/wallet/components/WalletDropdownFundLink.tsx b/src/wallet/components/WalletDropdownFundLink.tsx index f357375e19..23979f8ae6 100644 --- a/src/wallet/components/WalletDropdownFundLink.tsx +++ b/src/wallet/components/WalletDropdownFundLink.tsx @@ -2,7 +2,8 @@ import { isValidElement, useMemo } from 'react'; import { FundWalletSvg } from '../../internal/svg/fundWallet'; import { cn, pressable, text as themeText } from '../../styles/theme'; import { version } from '../../version'; -import type { WalletDropdownFundLinkReact, WindowSizes } from '../types'; +import type { WalletDropdownFundLinkReact } from '../types'; +import { getWindowDimensions } from '../utils/getWindowDimensions'; export function WalletDropdownFundLink({ className, @@ -25,42 +26,15 @@ export function WalletDropdownFundLink({ const currentURL = window.location.href; const tabName = document.title; const fundingUrl = `http://keys.coinbase.com/funding?dappName=${tabName}&dappUrl=${currentURL}&onchainkit=${version}`; - const windowSizes: WindowSizes = { - 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]; - - // 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.max( - minHeight, - Math.round(vwToPx(Number.parseFloat(height))), - ); - - // 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 { width, height } = getWindowDimensions(windowSize); - const left = Math.round((window.screen.width - adjustedWidthPx) / 2); - const top = Math.round((window.screen.height - adjustedHeightPx) / 2); + const left = Math.round((window.screen.width - width) / 2); + const top = Math.round((window.screen.height - height) / 2); - const windowFeatures = `width=${adjustedWidthPx},height=${adjustedHeightPx},resizable,scrollbars=yes,status=1,left=${left},top=${top}`; + const windowFeatures = `width=${width},height=${height},resizable,scrollbars=yes,status=1,left=${left},top=${top}`; window.open(fundingUrl, 'Coinbase Fund Wallet', windowFeatures); }; diff --git a/src/wallet/utils/getWindowDimensions.test.ts b/src/wallet/utils/getWindowDimensions.test.ts new file mode 100644 index 0000000000..08de675858 --- /dev/null +++ b/src/wallet/utils/getWindowDimensions.test.ts @@ -0,0 +1,52 @@ +import { beforeEach, describe, expect, it } from 'vitest'; +import { getWindowDimensions } from './getWindowDimensions'; // Adjust the import path as needed + +describe('getWindowDimensions', () => { + beforeEach(() => { + // Mock window.innerWidth and window.innerHeight + Object.defineProperty(window, 'innerWidth', { + writable: true, + configurable: true, + value: 1000, + }); + Object.defineProperty(window, 'innerHeight', { + writable: true, + configurable: true, + value: 800, + }); + }); + + it('should return minimum width for small screens', () => { + window.innerWidth = 300; + window.innerHeight = 400; + + const result = getWindowDimensions('s'); + expect(result).toEqual({ width: 270, height: 350 }); + }); + + it('should calculate correct dimensions for medium size', () => { + const result = getWindowDimensions('m'); + expect(result).toEqual({ width: 290, height: 363 }); + }); + + it('should calculate correct dimensions for large size', () => { + const result = getWindowDimensions('l'); + expect(result).toEqual({ width: 350, height: 438 }); + }); + + it('should limit dimensions to 35vw for large viewport', () => { + window.innerWidth = 2000; + window.innerHeight = 1500; + + const result = getWindowDimensions('l'); + expect(result).toEqual({ width: 700, height: 875 }); + }); + + it('should handle different aspect ratios', () => { + window.innerWidth = 1920; + window.innerHeight = 1080; + + const result = getWindowDimensions('m'); + expect(result).toEqual({ width: 557, height: 696 }); + }); +}); diff --git a/src/wallet/utils/getWindowDimensions.ts b/src/wallet/utils/getWindowDimensions.ts new file mode 100644 index 0000000000..2e6b2b65a2 --- /dev/null +++ b/src/wallet/utils/getWindowDimensions.ts @@ -0,0 +1,35 @@ +import type { WindowSizes } from '../types'; + +const windowSizes: WindowSizes = { + s: { width: '23vw', height: '28.75vw' }, + m: { width: '29vw', height: '36.25vw' }, + l: { width: '35vw', height: '43.75vw' }, +}; + +export const getWindowDimensions = (size: keyof typeof windowSizes) => { + const { width, height } = windowSizes[size]; + + // 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.max( + minHeight, + Math.round(vwToPx(Number.parseFloat(height))), + ); + + // 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); + + return { width: adjustedWidthPx, height: adjustedHeightPx }; +}; From c2d8dfef9f555772e460cb10bc889aa976da819e Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 15:37:32 -0700 Subject: [PATCH 34/51] remove comment --- src/wallet/utils/getWindowDimensions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/utils/getWindowDimensions.test.ts b/src/wallet/utils/getWindowDimensions.test.ts index 08de675858..dd89e9a08b 100644 --- a/src/wallet/utils/getWindowDimensions.test.ts +++ b/src/wallet/utils/getWindowDimensions.test.ts @@ -1,5 +1,5 @@ import { beforeEach, describe, expect, it } from 'vitest'; -import { getWindowDimensions } from './getWindowDimensions'; // Adjust the import path as needed +import { getWindowDimensions } from './getWindowDimensions'; describe('getWindowDimensions', () => { beforeEach(() => { From a0f582937e59b441f0689cdcb8ddafedc39e9d39 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Fri, 9 Aug 2024 15:45:10 -0700 Subject: [PATCH 35/51] `overrideClassName` --- src/wallet/components/WalletDropdownFundLink.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wallet/components/WalletDropdownFundLink.tsx b/src/wallet/components/WalletDropdownFundLink.tsx index 23979f8ae6..a5b2d5cc01 100644 --- a/src/wallet/components/WalletDropdownFundLink.tsx +++ b/src/wallet/components/WalletDropdownFundLink.tsx @@ -38,7 +38,7 @@ export function WalletDropdownFundLink({ window.open(fundingUrl, 'Coinbase Fund Wallet', windowFeatures); }; - const commonClassName = cn( + const overrideClassName = cn( pressable.default, 'relative flex items-center px-4 py-3', className, @@ -56,7 +56,7 @@ export function WalletDropdownFundLink({ if (openIn === 'tab') { return ( + ); From c1d33652379e51b65511b0b6b1291dc342717d82 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Wed, 14 Aug 2024 10:53:35 -0700 Subject: [PATCH 36/51] update funding url --- src/wallet/components/WalletDropdownFundLink.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/components/WalletDropdownFundLink.tsx b/src/wallet/components/WalletDropdownFundLink.tsx index a5b2d5cc01..9eb1268395 100644 --- a/src/wallet/components/WalletDropdownFundLink.tsx +++ b/src/wallet/components/WalletDropdownFundLink.tsx @@ -25,7 +25,7 @@ export function WalletDropdownFundLink({ const currentURL = window.location.href; const tabName = document.title; - const fundingUrl = `http://keys.coinbase.com/funding?dappName=${tabName}&dappUrl=${currentURL}&onchainkit=${version}`; + const fundingUrl = `http://keys.coinbase.com/fund?dappName=${tabName}&dappUrl=${currentURL}&onchainkit=${version}`; const handleClick = (e: React.MouseEvent) => { e.preventDefault(); From a9c6a57088fe44f204a483f5a4a2ed9d38cf53e0 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Wed, 14 Aug 2024 11:01:00 -0700 Subject: [PATCH 37/51] `windowSize` -> `popupSize` --- site/docs/pages/wallet/types.mdx | 2 +- .../components/WalletDropdownFundLink.test.tsx | 10 +++++----- src/wallet/components/WalletDropdownFundLink.tsx | 4 ++-- src/wallet/types.ts | 4 ++-- src/wallet/utils/getWindowDimensions.ts | 12 ++++++------ 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/site/docs/pages/wallet/types.mdx b/site/docs/pages/wallet/types.mdx index f0322fbb6d..ef31d99f05 100644 --- a/site/docs/pages/wallet/types.mdx +++ b/site/docs/pages/wallet/types.mdx @@ -93,7 +93,7 @@ export type WalletDropdownFundLinkReact = { openIn?: 'window' | 'tab'; // Whether to open the funding flow in a tab or a window target?: string; // Where to open the target if `openIn` is set to tab text?: string; // Optional text override - windowSize?: 's' | 'm' | 'l'; // Size of the popup window if `openIn` is set to window + popupSize?: 'sm' | 'md' | 'lg'; // Size of the popup window if `openIn` is set to window }; ``` diff --git a/src/wallet/components/WalletDropdownFundLink.test.tsx b/src/wallet/components/WalletDropdownFundLink.test.tsx index 0fc6ae2d1d..03309a4e52 100644 --- a/src/wallet/components/WalletDropdownFundLink.test.tsx +++ b/src/wallet/components/WalletDropdownFundLink.test.tsx @@ -63,16 +63,16 @@ describe('WalletDropdownFundLink', () => { }); const testCases: WindowSizes = { - s: { width: '23vw', height: '28.75vw' }, - m: { width: '29vw', height: '36.25vw' }, - l: { width: '35vw', height: '43.75vw' }, + sm: { width: '23vw', height: '28.75vw' }, + md: { width: '29vw', height: '36.25vw' }, + lg: { 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}"`, () => { + it(`opens a new window when clicked with type="window" and popupSize="${size}"`, () => { const mockOpen = vi.fn(); const screenWidth = 1024; const screenHeight = 768; @@ -85,7 +85,7 @@ describe('WalletDropdownFundLink', () => { render( , ); diff --git a/src/wallet/components/WalletDropdownFundLink.tsx b/src/wallet/components/WalletDropdownFundLink.tsx index 9eb1268395..7da569ea81 100644 --- a/src/wallet/components/WalletDropdownFundLink.tsx +++ b/src/wallet/components/WalletDropdownFundLink.tsx @@ -12,7 +12,7 @@ export function WalletDropdownFundLink({ openIn = 'tab', target, text = 'Fund wallet', - windowSize = 'm', + popupSize = 'md', }: WalletDropdownFundLinkReact) { const iconSvg = useMemo(() => { if (icon === undefined) { @@ -29,7 +29,7 @@ export function WalletDropdownFundLink({ const handleClick = (e: React.MouseEvent) => { e.preventDefault(); - const { width, height } = getWindowDimensions(windowSize); + const { width, height } = getWindowDimensions(popupSize); const left = Math.round((window.screen.width - width) / 2); const top = Math.round((window.screen.height - height) / 2); diff --git a/src/wallet/types.ts b/src/wallet/types.ts index b5ae464d3a..c9479e4cfd 100644 --- a/src/wallet/types.ts +++ b/src/wallet/types.ts @@ -107,7 +107,7 @@ export type WalletDropdownFundLinkReact = { openIn?: 'window' | 'tab'; // Whether to open the funding flow in a tab or a window target?: string; // Where to open the target if `openIn` is set to tab text?: string; // Optional text override - windowSize?: 's' | 'm' | 'l'; // Size of the popup window if `openIn` is set to window + popupSize?: 'sm' | 'md' | 'lg'; // Size of the popup window if `openIn` is set to window }; /** @@ -123,7 +123,7 @@ export type WalletDropdownLinkReact = { }; export type WindowSizes = Record< - 's' | 'm' | 'l', + 'sm' | 'md' | 'lg', { width: string; height: string; diff --git a/src/wallet/utils/getWindowDimensions.ts b/src/wallet/utils/getWindowDimensions.ts index 2e6b2b65a2..2709ef77e0 100644 --- a/src/wallet/utils/getWindowDimensions.ts +++ b/src/wallet/utils/getWindowDimensions.ts @@ -1,13 +1,13 @@ import type { WindowSizes } from '../types'; -const windowSizes: WindowSizes = { - s: { width: '23vw', height: '28.75vw' }, - m: { width: '29vw', height: '36.25vw' }, - l: { width: '35vw', height: '43.75vw' }, +const popupSizes: WindowSizes = { + sm: { width: '23vw', height: '28.75vw' }, + md: { width: '29vw', height: '36.25vw' }, + lg: { width: '35vw', height: '43.75vw' }, }; -export const getWindowDimensions = (size: keyof typeof windowSizes) => { - const { width, height } = windowSizes[size]; +export const getWindowDimensions = (size: keyof typeof popupSizes) => { + const { width, height } = popupSizes[size]; // Define minimum sizes (in pixels) const minWidth = 280; From f162d4b71a2d80cf834b3546cc3a6b735660ea94 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Wed, 14 Aug 2024 11:03:57 -0700 Subject: [PATCH 38/51] `openIn=window` -> `popup` --- site/docs/pages/wallet/types.mdx | 4 ++-- src/wallet/components/WalletDropdownFundLink.test.tsx | 4 ++-- src/wallet/types.ts | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/site/docs/pages/wallet/types.mdx b/site/docs/pages/wallet/types.mdx index ef31d99f05..bc22cb9df1 100644 --- a/site/docs/pages/wallet/types.mdx +++ b/site/docs/pages/wallet/types.mdx @@ -90,10 +90,10 @@ export type WalletDropdownFundLinkReact = { href: string; icon?: ReactNode; rel?: string; - openIn?: 'window' | 'tab'; // Whether to open the funding flow in a tab or a window + openIn?: 'popup' | 'tab'; // Whether to open the funding flow in a tab or a popup window target?: string; // Where to open the target if `openIn` is set to tab text?: string; // Optional text override - popupSize?: 'sm' | 'md' | 'lg'; // Size of the popup window if `openIn` is set to window + popupSize?: 'sm' | 'md' | 'lg'; // Size of the popup window if `openIn` is set to `popup` }; ``` diff --git a/src/wallet/components/WalletDropdownFundLink.test.tsx b/src/wallet/components/WalletDropdownFundLink.test.tsx index 03309a4e52..868f04645c 100644 --- a/src/wallet/components/WalletDropdownFundLink.test.tsx +++ b/src/wallet/components/WalletDropdownFundLink.test.tsx @@ -44,7 +44,7 @@ describe('WalletDropdownFundLink', () => { // Mock window.screen vi.stubGlobal('screen', { width: 1024, height: 768 }); - render(); + render(); const linkElement = screen.getByText('Fund wallet'); fireEvent.click(linkElement); @@ -84,7 +84,7 @@ describe('WalletDropdownFundLink', () => { render( , ); diff --git a/src/wallet/types.ts b/src/wallet/types.ts index c9479e4cfd..ce9abf2d3f 100644 --- a/src/wallet/types.ts +++ b/src/wallet/types.ts @@ -104,10 +104,10 @@ export type WalletDropdownFundLinkReact = { href: string; icon?: ReactNode; rel?: string; - openIn?: 'window' | 'tab'; // Whether to open the funding flow in a tab or a window + openIn?: 'popup' | 'tab'; // Whether to open the funding flow in a tab or a popup window target?: string; // Where to open the target if `openIn` is set to tab text?: string; // Optional text override - popupSize?: 'sm' | 'md' | 'lg'; // Size of the popup window if `openIn` is set to window + popupSize?: 'sm' | 'md' | 'lg'; // Size of the popup window if `openIn` is set to `popup` }; /** From 0ba3f3cbb158dbf694fef6c5ba7639b2356b51a0 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Wed, 14 Aug 2024 11:29:13 -0700 Subject: [PATCH 39/51] fix tests --- src/wallet/components/WalletDropdownFundLink.test.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wallet/components/WalletDropdownFundLink.test.tsx b/src/wallet/components/WalletDropdownFundLink.test.tsx index 868f04645c..1e838215e7 100644 --- a/src/wallet/components/WalletDropdownFundLink.test.tsx +++ b/src/wallet/components/WalletDropdownFundLink.test.tsx @@ -4,7 +4,7 @@ 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}`; +const FUNDING_URL = `http://keys.coinbase.com/fund?dappName=&dappUrl=http://localhost:3000/&onchainkit=${version}`; describe('WalletDropdownFundLink', () => { it('renders correctly with default props', () => { @@ -51,7 +51,7 @@ describe('WalletDropdownFundLink', () => { // Check if window.open was called with the correct arguments expect(mockOpen).toHaveBeenCalledWith( - expect.stringContaining('http://keys.coinbase.com/funding'), + expect.stringContaining('http://keys.coinbase.com/fund'), 'Coinbase Fund Wallet', expect.stringContaining( 'width=297,height=371,resizable,scrollbars=yes,status=1,left=364,top=199', @@ -104,7 +104,7 @@ describe('WalletDropdownFundLink', () => { const expectedLeft = Math.round((screenWidth - expectedWidth) / 2); const expectedTop = Math.round((screenHeight - adjustedHeight) / 2); expect(mockOpen).toHaveBeenCalledWith( - expect.stringContaining('http://keys.coinbase.com/funding'), + expect.stringContaining('http://keys.coinbase.com/fund'), 'Coinbase Fund Wallet', expect.stringContaining( `width=${expectedWidth},height=${adjustedHeight},resizable,scrollbars=yes,status=1,left=${expectedLeft},top=${expectedTop}`, From 07d4bf3b855bd7655d76a693cfdd47dbd61bd93f Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Wed, 14 Aug 2024 11:56:19 -0700 Subject: [PATCH 40/51] fix dimensions tests --- src/wallet/utils/getWindowDimensions.test.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/wallet/utils/getWindowDimensions.test.ts b/src/wallet/utils/getWindowDimensions.test.ts index dd89e9a08b..f89354d2a1 100644 --- a/src/wallet/utils/getWindowDimensions.test.ts +++ b/src/wallet/utils/getWindowDimensions.test.ts @@ -20,17 +20,17 @@ describe('getWindowDimensions', () => { window.innerWidth = 300; window.innerHeight = 400; - const result = getWindowDimensions('s'); + const result = getWindowDimensions('sm'); expect(result).toEqual({ width: 270, height: 350 }); }); it('should calculate correct dimensions for medium size', () => { - const result = getWindowDimensions('m'); + const result = getWindowDimensions('md'); expect(result).toEqual({ width: 290, height: 363 }); }); it('should calculate correct dimensions for large size', () => { - const result = getWindowDimensions('l'); + const result = getWindowDimensions('lg'); expect(result).toEqual({ width: 350, height: 438 }); }); @@ -38,7 +38,7 @@ describe('getWindowDimensions', () => { window.innerWidth = 2000; window.innerHeight = 1500; - const result = getWindowDimensions('l'); + const result = getWindowDimensions('lg'); expect(result).toEqual({ width: 700, height: 875 }); }); @@ -46,7 +46,7 @@ describe('getWindowDimensions', () => { window.innerWidth = 1920; window.innerHeight = 1080; - const result = getWindowDimensions('m'); + const result = getWindowDimensions('md'); expect(result).toEqual({ width: 557, height: 696 }); }); }); From 5cda967ebaeff65346e1756202cb973249c12ed5 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Wed, 14 Aug 2024 12:35:14 -0700 Subject: [PATCH 41/51] change query params --- src/wallet/components/WalletDropdownFundLink.test.tsx | 2 +- src/wallet/components/WalletDropdownFundLink.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/components/WalletDropdownFundLink.test.tsx b/src/wallet/components/WalletDropdownFundLink.test.tsx index 1e838215e7..61a4a3d982 100644 --- a/src/wallet/components/WalletDropdownFundLink.test.tsx +++ b/src/wallet/components/WalletDropdownFundLink.test.tsx @@ -4,7 +4,7 @@ import { version } from '../../version'; import type { WindowSizes } from '../types'; import { WalletDropdownFundLink } from './WalletDropdownFundLink'; -const FUNDING_URL = `http://keys.coinbase.com/fund?dappName=&dappUrl=http://localhost:3000/&onchainkit=${version}`; +const FUNDING_URL = `http://keys.coinbase.com/fund?dappName=&dappUrl=http://localhost:3000/&version=${version}&source=onchainkit`; describe('WalletDropdownFundLink', () => { it('renders correctly with default props', () => { diff --git a/src/wallet/components/WalletDropdownFundLink.tsx b/src/wallet/components/WalletDropdownFundLink.tsx index 7da569ea81..91c8e910b5 100644 --- a/src/wallet/components/WalletDropdownFundLink.tsx +++ b/src/wallet/components/WalletDropdownFundLink.tsx @@ -25,7 +25,7 @@ export function WalletDropdownFundLink({ const currentURL = window.location.href; const tabName = document.title; - const fundingUrl = `http://keys.coinbase.com/fund?dappName=${tabName}&dappUrl=${currentURL}&onchainkit=${version}`; + const fundingUrl = `http://keys.coinbase.com/fund?dappName=${tabName}&dappUrl=${currentURL}&version=${version}&source=onchainkit`; const handleClick = (e: React.MouseEvent) => { e.preventDefault(); From 0b536ac7f4beb722fba09938d80be35857241728 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Wed, 14 Aug 2024 13:01:31 -0700 Subject: [PATCH 42/51] tweak size of `sm` --- src/wallet/utils/getWindowDimensions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/utils/getWindowDimensions.ts b/src/wallet/utils/getWindowDimensions.ts index 2709ef77e0..eb5ee11268 100644 --- a/src/wallet/utils/getWindowDimensions.ts +++ b/src/wallet/utils/getWindowDimensions.ts @@ -1,7 +1,7 @@ import type { WindowSizes } from '../types'; const popupSizes: WindowSizes = { - sm: { width: '23vw', height: '28.75vw' }, + sm: { width: '24.67vw', height: '30.83vw' }, md: { width: '29vw', height: '36.25vw' }, lg: { width: '35vw', height: '43.75vw' }, }; From 6874ac222a69bbe8d8a13f3eba35b192e57959b0 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Wed, 14 Aug 2024 13:01:42 -0700 Subject: [PATCH 43/51] add `popupFeatures` as an override --- src/wallet/components/WalletDropdownFundLink.tsx | 5 ++++- src/wallet/types.ts | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/wallet/components/WalletDropdownFundLink.tsx b/src/wallet/components/WalletDropdownFundLink.tsx index 91c8e910b5..da7e3e0849 100644 --- a/src/wallet/components/WalletDropdownFundLink.tsx +++ b/src/wallet/components/WalletDropdownFundLink.tsx @@ -9,6 +9,7 @@ export function WalletDropdownFundLink({ className, icon, rel, + popupFeatures, openIn = 'tab', target, text = 'Fund wallet', @@ -34,7 +35,9 @@ export function WalletDropdownFundLink({ const left = Math.round((window.screen.width - width) / 2); const top = Math.round((window.screen.height - height) / 2); - const windowFeatures = `width=${width},height=${height},resizable,scrollbars=yes,status=1,left=${left},top=${top}`; + const windowFeatures = + popupFeatures || + `width=${width},height=${height},resizable,scrollbars=yes,status=1,left=${left},top=${top}`; window.open(fundingUrl, 'Coinbase Fund Wallet', windowFeatures); }; diff --git a/src/wallet/types.ts b/src/wallet/types.ts index ce9abf2d3f..93821f77b6 100644 --- a/src/wallet/types.ts +++ b/src/wallet/types.ts @@ -105,9 +105,10 @@ export type WalletDropdownFundLinkReact = { icon?: ReactNode; rel?: string; openIn?: 'popup' | 'tab'; // Whether to open the funding flow in a tab or a popup window + popupFeatures?: string; // Optional features override for the popup window if `openIn` is set to `popup` + popupSize?: 'sm' | 'md' | 'lg'; // Size of the popup window if `openIn` is set to `popup` target?: string; // Where to open the target if `openIn` is set to tab text?: string; // Optional text override - popupSize?: 'sm' | 'md' | 'lg'; // Size of the popup window if `openIn` is set to `popup` }; /** From e2629682d3f207f88394620f09984bd169fbf72b Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Wed, 14 Aug 2024 14:36:56 -0700 Subject: [PATCH 44/51] fixes --- src/internal/svg/fundWallet.tsx | 6 +++--- src/wallet/components/WalletDropdownFundLink.test.tsx | 4 ++-- src/wallet/components/WalletDropdownFundLink.tsx | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/internal/svg/fundWallet.tsx b/src/internal/svg/fundWallet.tsx index a71f805203..ccca7ee7ce 100644 --- a/src/internal/svg/fundWallet.tsx +++ b/src/internal/svg/fundWallet.tsx @@ -4,9 +4,9 @@ export const FundWalletSvg = ( diff --git a/src/wallet/components/WalletDropdownFundLink.test.tsx b/src/wallet/components/WalletDropdownFundLink.test.tsx index 61a4a3d982..406e73e486 100644 --- a/src/wallet/components/WalletDropdownFundLink.test.tsx +++ b/src/wallet/components/WalletDropdownFundLink.test.tsx @@ -52,7 +52,7 @@ describe('WalletDropdownFundLink', () => { // Check if window.open was called with the correct arguments expect(mockOpen).toHaveBeenCalledWith( expect.stringContaining('http://keys.coinbase.com/fund'), - 'Coinbase Fund Wallet', + undefined, expect.stringContaining( 'width=297,height=371,resizable,scrollbars=yes,status=1,left=364,top=199', ), @@ -105,7 +105,7 @@ describe('WalletDropdownFundLink', () => { const expectedTop = Math.round((screenHeight - adjustedHeight) / 2); expect(mockOpen).toHaveBeenCalledWith( expect.stringContaining('http://keys.coinbase.com/fund'), - 'Coinbase Fund Wallet', + undefined, expect.stringContaining( `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 da7e3e0849..e860fae8a5 100644 --- a/src/wallet/components/WalletDropdownFundLink.tsx +++ b/src/wallet/components/WalletDropdownFundLink.tsx @@ -38,7 +38,7 @@ export function WalletDropdownFundLink({ const windowFeatures = popupFeatures || `width=${width},height=${height},resizable,scrollbars=yes,status=1,left=${left},top=${top}`; - window.open(fundingUrl, 'Coinbase Fund Wallet', windowFeatures); + window.open(fundingUrl, target, windowFeatures); }; const overrideClassName = cn( From 3f15e987871cfbf4472dcff3f9351edeef5b1663 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Wed, 14 Aug 2024 15:24:27 -0700 Subject: [PATCH 45/51] add comments --- site/docs/pages/wallet/types.mdx | 5 ++--- src/wallet/types.ts | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/site/docs/pages/wallet/types.mdx b/site/docs/pages/wallet/types.mdx index bc22cb9df1..dde1c073f4 100644 --- a/site/docs/pages/wallet/types.mdx +++ b/site/docs/pages/wallet/types.mdx @@ -87,9 +87,8 @@ export type WalletDropdownDisconnectReact = { ```ts export type WalletDropdownFundLinkReact = { className?: string; // Optional className override for the element - href: string; - icon?: ReactNode; - rel?: string; + icon?: ReactNode; // Optional icon override + rel?: string; // Specifies the relationship between the current document and the linked document openIn?: 'popup' | 'tab'; // Whether to open the funding flow in a tab or a popup window target?: string; // Where to open the target if `openIn` is set to tab text?: string; // Optional text override diff --git a/src/wallet/types.ts b/src/wallet/types.ts index 93821f77b6..30d0f6b0e8 100644 --- a/src/wallet/types.ts +++ b/src/wallet/types.ts @@ -101,9 +101,8 @@ export type WalletDropdownDisconnectReact = { */ export type WalletDropdownFundLinkReact = { className?: string; // Optional className override for the element - href: string; - icon?: ReactNode; - rel?: string; + icon?: ReactNode; // Optional icon override + rel?: string; // Specifies the relationship between the current document and the linked document openIn?: 'popup' | 'tab'; // Whether to open the funding flow in a tab or a popup window popupFeatures?: string; // Optional features override for the popup window if `openIn` is set to `popup` popupSize?: 'sm' | 'md' | 'lg'; // Size of the popup window if `openIn` is set to `popup` From 09e82f7fd8861f39ca133bc5e57207f9705f9de8 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Wed, 14 Aug 2024 15:25:56 -0700 Subject: [PATCH 46/51] wrap using `useMemo` and `useCallback` --- .../components/WalletDropdownFundLink.tsx | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/wallet/components/WalletDropdownFundLink.tsx b/src/wallet/components/WalletDropdownFundLink.tsx index e860fae8a5..e1a7566f2d 100644 --- a/src/wallet/components/WalletDropdownFundLink.tsx +++ b/src/wallet/components/WalletDropdownFundLink.tsx @@ -1,4 +1,4 @@ -import { isValidElement, useMemo } from 'react'; +import { isValidElement, useCallback, useMemo } from 'react'; import { FundWalletSvg } from '../../internal/svg/fundWallet'; import { cn, pressable, text as themeText } from '../../styles/theme'; import { version } from '../../version'; @@ -28,18 +28,21 @@ export function WalletDropdownFundLink({ const tabName = document.title; const fundingUrl = `http://keys.coinbase.com/fund?dappName=${tabName}&dappUrl=${currentURL}&version=${version}&source=onchainkit`; - const handleClick = (e: React.MouseEvent) => { - e.preventDefault(); - const { width, height } = getWindowDimensions(popupSize); + const handleClick = useCallback( + (e: React.MouseEvent) => { + e.preventDefault(); + const { width, height } = getWindowDimensions(popupSize); - const left = Math.round((window.screen.width - width) / 2); - const top = Math.round((window.screen.height - height) / 2); + const left = Math.round((window.screen.width - width) / 2); + const top = Math.round((window.screen.height - height) / 2); - const windowFeatures = - popupFeatures || - `width=${width},height=${height},resizable,scrollbars=yes,status=1,left=${left},top=${top}`; - window.open(fundingUrl, target, windowFeatures); - }; + const windowFeatures = + popupFeatures || + `width=${width},height=${height},resizable,scrollbars=yes,status=1,left=${left},top=${top}`; + window.open(fundingUrl, target, windowFeatures); + }, + [fundingUrl, popupFeatures, popupSize, target], + ); const overrideClassName = cn( pressable.default, @@ -47,13 +50,16 @@ export function WalletDropdownFundLink({ className, ); - const linkContent = ( - <> -
- {iconSvg} -
- {text} - + const linkContent = useMemo( + () => ( + <> +
+ {iconSvg} +
+ {text} + + ), + [iconSvg, text], ); if (openIn === 'tab') { From 56a243ae96a75148867e8040a890a7fb53a7ec8f Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Wed, 14 Aug 2024 16:57:54 -0700 Subject: [PATCH 47/51] `useIcon` hook --- src/internal/svg/fundWallet.tsx | 2 +- .../components/WalletDropdownFundLink.tsx | 15 ++--- src/wallet/components/WalletDropdownLink.tsx | 16 +---- src/wallet/hooks/useIcon.test.tsx | 63 +++++++++++++++++++ src/wallet/hooks/useIcon.tsx | 20 ++++++ 5 files changed, 90 insertions(+), 26 deletions(-) create mode 100644 src/wallet/hooks/useIcon.test.tsx create mode 100644 src/wallet/hooks/useIcon.tsx diff --git a/src/internal/svg/fundWallet.tsx b/src/internal/svg/fundWallet.tsx index ccca7ee7ce..2e55a2e952 100644 --- a/src/internal/svg/fundWallet.tsx +++ b/src/internal/svg/fundWallet.tsx @@ -1,6 +1,6 @@ import { fill } from '../../styles/theme'; -export const FundWalletSvg = ( +export const fundWalletSvg = ( { - if (icon === undefined) { - return FundWalletSvg; - } - if (isValidElement(icon)) { - return icon; - } - }, [icon]); + const iconSvg = useIcon({ icon }); const currentURL = window.location.href; const tabName = document.title; diff --git a/src/wallet/components/WalletDropdownLink.tsx b/src/wallet/components/WalletDropdownLink.tsx index 3801126149..0f04539083 100644 --- a/src/wallet/components/WalletDropdownLink.tsx +++ b/src/wallet/components/WalletDropdownLink.tsx @@ -1,6 +1,5 @@ -import { isValidElement, useMemo } from 'react'; -import { walletSvg } from '../../internal/svg/walletSvg'; import { cn, pressable, text } from '../../styles/theme'; +import { useIcon } from '../hooks/useIcon'; import type { WalletDropdownLinkReact } from '../types'; export function WalletDropdownLink({ @@ -11,18 +10,7 @@ export function WalletDropdownLink({ rel, target, }: WalletDropdownLinkReact) { - const iconSvg = useMemo(() => { - if (icon === undefined) { - return null; - } - switch (icon) { - case 'wallet': - return walletSvg; - } - if (isValidElement(icon)) { - return icon; - } - }, [icon]); + const iconSvg = useIcon({ icon }); return ( { + it('should return null when icon is undefined', () => { + const { result } = renderHook(() => useIcon({ icon: undefined })); + expect(result.current).toBeNull(); + }); + + it('should return walletSvg when icon is "wallet"', () => { + const { result } = renderHook(() => useIcon({ icon: 'wallet' })); + expect(result.current).toBe(walletSvg); + }); + + it('should return fundWalletSvg when icon is "fundWallet"', () => { + const { result } = renderHook(() => useIcon({ icon: 'fundWallet' })); + expect(result.current).toBe(fundWalletSvg); + }); + + it('should memoize the result for undefined', () => { + const { result, rerender } = renderHook(() => useIcon({}), { + initialProps: {}, + }); + + const initialResult = result.current; + rerender({}); + expect(result.current).toBe(initialResult); + }); + + it('should memoize the result for wallet', () => { + const { result, rerender } = renderHook(({ icon }) => useIcon({ icon }), { + initialProps: { icon: 'wallet' }, + }); + + const initialResult = result.current; + rerender({ icon: 'wallet' }); + expect(result.current).toBe(initialResult); + }); + + it('should memoize the result for fundWallet', () => { + const { result, rerender } = renderHook(({ icon }) => useIcon({ icon }), { + initialProps: { icon: 'fundWallet' }, + }); + + const initialResult = result.current; + rerender({ icon: 'fundWallet' }); + expect(result.current).toBe(initialResult); + }); + + it('should memoize the result for custom icon', () => { + const customIcon = ; + const { result, rerender } = renderHook(({ icon }) => useIcon({ icon }), { + initialProps: { icon: customIcon }, + }); + + const initialResult = result.current; + rerender({ icon: customIcon }); + expect(result.current).toBe(initialResult); + }); +}); diff --git a/src/wallet/hooks/useIcon.tsx b/src/wallet/hooks/useIcon.tsx new file mode 100644 index 0000000000..468a5874e9 --- /dev/null +++ b/src/wallet/hooks/useIcon.tsx @@ -0,0 +1,20 @@ +import { isValidElement, useMemo } from 'react'; +import { fundWalletSvg } from '../../internal/svg/fundWallet'; +import { walletSvg } from '../../internal/svg/walletSvg'; + +export const useIcon = ({ icon }: { icon?: React.ReactNode }) => { + return useMemo(() => { + if (icon === undefined) { + return null; + } + switch (icon) { + case 'wallet': + return walletSvg; + case 'fundWallet': + return fundWalletSvg; + } + if (isValidElement(icon)) { + return icon; + } + }, [icon]); +}; From a4ba654d0dda7b123c21d2d9bd1cfa5b3a6b31fc Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Wed, 14 Aug 2024 17:03:39 -0700 Subject: [PATCH 48/51] `useEffect` for `fundingUrl` --- .../components/WalletDropdownFundLink.test.tsx | 2 +- src/wallet/components/WalletDropdownFundLink.tsx | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/wallet/components/WalletDropdownFundLink.test.tsx b/src/wallet/components/WalletDropdownFundLink.test.tsx index 406e73e486..1294112081 100644 --- a/src/wallet/components/WalletDropdownFundLink.test.tsx +++ b/src/wallet/components/WalletDropdownFundLink.test.tsx @@ -4,7 +4,7 @@ import { version } from '../../version'; import type { WindowSizes } from '../types'; import { WalletDropdownFundLink } from './WalletDropdownFundLink'; -const FUNDING_URL = `http://keys.coinbase.com/fund?dappName=&dappUrl=http://localhost:3000/&version=${version}&source=onchainkit`; +const FUNDING_URL = `http://keys.coinbase.com/fund?dappName=&dappUrl=http%3A%2F%2Flocalhost%3A3000%2F&version=${version}&source=onchainkit`; describe('WalletDropdownFundLink', () => { it('renders correctly with default props', () => { diff --git a/src/wallet/components/WalletDropdownFundLink.tsx b/src/wallet/components/WalletDropdownFundLink.tsx index 724c57a2a8..1074e3b97e 100644 --- a/src/wallet/components/WalletDropdownFundLink.tsx +++ b/src/wallet/components/WalletDropdownFundLink.tsx @@ -1,4 +1,5 @@ import { useCallback, useMemo } from 'react'; +import { useEffect, useState } from 'react'; import { cn, pressable, text as themeText } from '../../styles/theme'; import { version } from '../../version'; import { useIcon } from '../hooks/useIcon'; @@ -15,11 +16,20 @@ export function WalletDropdownFundLink({ text = 'Fund wallet', popupSize = 'md', }: WalletDropdownFundLinkReact) { + const [fundingUrl, setFundingUrl] = useState(''); + const iconSvg = useIcon({ icon }); - const currentURL = window.location.href; - const tabName = document.title; - const fundingUrl = `http://keys.coinbase.com/fund?dappName=${tabName}&dappUrl=${currentURL}&version=${version}&source=onchainkit`; + useEffect(() => { + const currentURL = window.location.href; + const tabName = document.title; + const url = `http://keys.coinbase.com/fund?dappName=${encodeURIComponent( + tabName, + )}&dappUrl=${encodeURIComponent(currentURL)}&version=${encodeURIComponent( + version, + )}&source=onchainkit`; + setFundingUrl(url); + }, []); const handleClick = useCallback( (e: React.MouseEvent) => { From 91ee34e332b739d9c9d9220d84c154e49bc937f6 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Wed, 14 Aug 2024 17:32:46 -0700 Subject: [PATCH 49/51] Update witty-crabs-change.md --- .changeset/witty-crabs-change.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/witty-crabs-change.md b/.changeset/witty-crabs-change.md index 0400391d4b..169f381068 100644 --- a/.changeset/witty-crabs-change.md +++ b/.changeset/witty-crabs-change.md @@ -2,4 +2,4 @@ "@coinbase/onchainkit": patch --- -**feat**: `WalletDropdownFundLink` - add a wallet dropdown component for the keys.coinbase.com funding flow by @0xAlec #1021 +**feat**: `WalletDropdownFundLink` - add a wallet dropdown link for the keys.coinbase.com funding flow by @0xAlec #1021 From df97e48f47cb57feb6094a087d3db723e01f7d04 Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Wed, 14 Aug 2024 18:11:45 -0700 Subject: [PATCH 50/51] alphabetical order --- site/docs/pages/wallet/types.mdx | 5 +++-- src/wallet/components/WalletDropdownFundLink.tsx | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/site/docs/pages/wallet/types.mdx b/site/docs/pages/wallet/types.mdx index dde1c073f4..b10a8897f8 100644 --- a/site/docs/pages/wallet/types.mdx +++ b/site/docs/pages/wallet/types.mdx @@ -88,11 +88,12 @@ export type WalletDropdownDisconnectReact = { export type WalletDropdownFundLinkReact = { className?: string; // Optional className override for the element icon?: ReactNode; // Optional icon override - rel?: string; // Specifies the relationship between the current document and the linked document openIn?: 'popup' | 'tab'; // Whether to open the funding flow in a tab or a popup window + popupFeatures?: string; // Optional features override for the popup window if `openIn` is set to `popup` + popupSize?: 'sm' | 'md' | 'lg'; // Size of the popup window if `openIn` is set to `popup` + rel?: string; // Specifies the relationship between the current document and the linked document target?: string; // Where to open the target if `openIn` is set to tab text?: string; // Optional text override - popupSize?: 'sm' | 'md' | 'lg'; // Size of the popup window if `openIn` is set to `popup` }; ``` diff --git a/src/wallet/components/WalletDropdownFundLink.tsx b/src/wallet/components/WalletDropdownFundLink.tsx index 1074e3b97e..6ebfb8069f 100644 --- a/src/wallet/components/WalletDropdownFundLink.tsx +++ b/src/wallet/components/WalletDropdownFundLink.tsx @@ -9,12 +9,12 @@ import { getWindowDimensions } from '../utils/getWindowDimensions'; export function WalletDropdownFundLink({ className, icon = 'fundWallet', - rel, - popupFeatures, openIn = 'tab', + popupFeatures, + popupSize = 'md', + rel, target, text = 'Fund wallet', - popupSize = 'md', }: WalletDropdownFundLinkReact) { const [fundingUrl, setFundingUrl] = useState(''); From f040a52e2464991f976036a450f5ba93cd3d22fa Mon Sep 17 00:00:00 2001 From: Alec Chen <93971719+0xAlec@users.noreply.github.com> Date: Wed, 14 Aug 2024 18:12:28 -0700 Subject: [PATCH 51/51] alphabetical --- src/wallet/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/types.ts b/src/wallet/types.ts index 30d0f6b0e8..7782411331 100644 --- a/src/wallet/types.ts +++ b/src/wallet/types.ts @@ -102,10 +102,10 @@ export type WalletDropdownDisconnectReact = { export type WalletDropdownFundLinkReact = { className?: string; // Optional className override for the element icon?: ReactNode; // Optional icon override - rel?: string; // Specifies the relationship between the current document and the linked document openIn?: 'popup' | 'tab'; // Whether to open the funding flow in a tab or a popup window popupFeatures?: string; // Optional features override for the popup window if `openIn` is set to `popup` popupSize?: 'sm' | 'md' | 'lg'; // Size of the popup window if `openIn` is set to `popup` + rel?: string; // Specifies the relationship between the current document and the linked document target?: string; // Where to open the target if `openIn` is set to tab text?: string; // Optional text override };