Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion packages/dapp-kit/src/components/ConnectButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,54 @@ import { AccountDropdownMenu } from './AccountDropdownMenu.js';
import { ConnectModal } from './connect-modal/ConnectModal.js';
import { StyleMarker } from './styling/StyleMarker.js';
import { Button } from './ui/Button.js';
import { IconButton } from './ui/IconButton.js';

type ConnectButtonProps = {
connectText?: ReactNode;
/** Filter the wallets shown in the connect modal */
walletFilter?: (wallet: WalletWithRequiredFeatures) => boolean;
/** Optional icon to show before the text */
iconBefore?: ReactNode;
/** Optional icon to show after the text */
iconAfter?: ReactNode;
} & ButtonHTMLAttributes<HTMLButtonElement>;

export function ConnectButton({
connectText = 'Connect Wallet',
walletFilter,
iconBefore,
iconAfter,
...buttonProps
}: ConnectButtonProps) {
const currentAccount = useCurrentAccount();

return currentAccount ? (
<AccountDropdownMenu currentAccount={currentAccount} />
) : (
<ConnectModal
walletFilter={walletFilter}
trigger={
<StyleMarker>
<Button {...buttonProps}>{connectText}</Button>
<Button {...buttonProps}>
{/* Icon before */}
{iconBefore && (
<IconButton asChild aria-label="Icon before">
{iconBefore}
</IconButton>
)}

{connectText}

{/* Icon after */}
{iconAfter && (
<IconButton asChild aria-label="Icon after">
{iconAfter}
</IconButton>
)}
</Button>
</StyleMarker>
}
/>
);
}

31 changes: 29 additions & 2 deletions packages/dapp-kit/test/components/ConnectButton.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,39 @@ import { ConnectButton } from '../../src/components/ConnectButton';
import { createWalletProviderContextWrapper } from '../test-utils';

describe('ConnectButton', () => {
test('renders iconBefore and iconAfter', () => {
const wrapper = createWalletProviderContextWrapper();

render(
<ConnectButton
connectText="Connect Wallet"
iconBefore={<span data-testid="icon-before">Icon Before</span>}
iconAfter={<span data-testid="icon-after">Icon After</span>}
/>,
{ wrapper }
);

// Check button text
expect(screen.getByRole('button', { name: /connect wallet/i })).toBeInTheDocument();

// Check iconBefore
expect(screen.getByTestId('icon-before')).toBeInTheDocument();
expect(screen.getByTestId('icon-before')).toHaveTextContent('Icon Before');

// Check iconAfter
expect(screen.getByTestId('icon-after')).toBeInTheDocument();
expect(screen.getByTestId('icon-after')).toHaveTextContent('Icon After');
});

test('clicking the button opens the connect modal', async () => {
const wrapper = createWalletProviderContextWrapper();

render(<ConnectButton />, { wrapper });
render(
<ConnectButton connectText="Connect Wallet" />,
{ wrapper }
);

const connectButtonEl = screen.getByRole('button', { name: 'Connect Wallet' });
const connectButtonEl = screen.getByRole('button', { name: /connect wallet/i });
expect(connectButtonEl).toBeInTheDocument();

const user = userEvent.setup();
Expand Down
4 changes: 3 additions & 1 deletion packages/dapp-kit/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
"outDir": "dist/cjs",
"isolatedModules": true,
"jsx": "react-jsx",
"rootDir": "src"
"rootDir": "src",
"types": ["react"],
"lib": ["dom", "esnext"]
},
"references": [
{ "path": "../typescript" },
Expand Down