Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: optimized connect-button code #481

Merged
merged 10 commits into from
Jan 12, 2024
5 changes: 5 additions & 0 deletions .changeset/thick-singers-deny.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@ant-design/web3': patch
---

refactor: Optimization ConnectButton code
113 changes: 53 additions & 60 deletions packages/web3/src/connect-button/connect-button.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useContext, useMemo, useState } from 'react';
import { CopyOutlined, LoginOutlined, UserOutlined } from '@ant-design/icons';
import type { Chain } from '@ant-design/web3-common';
import type { ButtonProps } from 'antd';
import { Avatar, Button, ConfigProvider, Divider, Dropdown, message, Space } from 'antd';
import type { MenuItemType } from 'antd/es/menu/hooks/useItems';
Expand All @@ -8,9 +9,12 @@ import classNames from 'classnames';
import { Address } from '../address';
import { CryptoPrice } from '../crypto-price';
import useIntl from '../hooks/useIntl';
import type { IntlType } from '../hooks/useIntl';
import { fillWith0x, writeCopyText } from '../utils';
import { ChainSelect } from './chain-select';
import type { ChainSelectProps } from './chain-select';
import type { ConnectButtonProps, ConnectButtonTooltipProps } from './interface';
import type { ProfileModalProps } from './profile-modal';
import { ProfileModal } from './profile-modal';
import { useStyle } from './style';
import { ConnectButtonTooltip } from './tooltip';
Expand Down Expand Up @@ -73,21 +77,39 @@ export const ConnectButton: React.FC<ConnectButtonProps> = (props) => {
...restProps,
};

const renderChainSelect = () => {
if (availableChains && availableChains.length > 1) {
return (
<ChainSelect
hashId={hashId}
onSwitchChain={onSwitchChain}
currentChain={chain}
chains={availableChains}
/>
);
}
return null;
const chainProps: ChainSelectProps = {
hashId,
onSwitchChain,
currentChain: chain,
chains: availableChains as Chain[],
};

const chainSelect = renderChainSelect();
const profileModalProps: ProfileModalProps = {
intl,
open: profileOpen,
__hashId__: hashId,
onDisconnect: () => {
setProfileOpen(false);
onDisconnectClick?.();
},
onClose: () => {
setProfileOpen(false);
},
address: account?.address,
name: account?.name,
avatar: avatar ?? {
icon: chain?.icon ? (
<div className={`${prefixCls}-chain-icon`}>{chain?.icon}</div>
) : (
<UserOutlined className={`${prefixCls}-default-icon`} />
),
},
balance,
modalProps: typeof profileModal === 'object' ? profileModal : undefined,
};

const chainSelect =
availableChains && availableChains.length > 1 ? <ChainSelect {...chainProps} /> : null;

const buttonInnerText = (
<div className={`${prefixCls}-content`}>
Expand All @@ -114,36 +136,6 @@ export const ConnectButton: React.FC<ConnectButtonProps> = (props) => {
<Button {...buttonProps}>{buttonInnerText}</Button>
);

const profileModalContent = (
<ProfileModal
intl={intl}
open={profileOpen}
__hashId__={hashId}
onDisconnect={() => {
setProfileOpen(false);
onDisconnectClick?.();
}}
onClose={() => {
setProfileOpen(false);
}}
address={account?.address}
name={account?.name}
avatar={
avatar ?? {
icon: chain?.icon ? (
<div className={`${prefixCls}-chain-icon`}>{chain?.icon}</div>
) : (
<UserOutlined className={`${prefixCls}-default-icon`} />
),
}
}
balance={balance}
modalProps={typeof profileModal === 'object' ? profileModal : undefined}
/>
);

let content = buttonContent;

const defaultMenuItems: MenuItemType[] = useMemo(
() => [
{
Expand Down Expand Up @@ -194,8 +186,8 @@ export const ConnectButton: React.FC<ConnectButtonProps> = (props) => {
return combinedItems;
}, [actionsMenu, defaultMenuItems, account]);

if (mergedMenuItems.length > 0) {
content = (
const content =
mergedMenuItems.length > 0 ? (
<Dropdown
open={showMenu}
onOpenChange={setShowMenu}
Expand All @@ -206,35 +198,36 @@ export const ConnectButton: React.FC<ConnectButtonProps> = (props) => {
>
{buttonContent}
</Dropdown>
) : (
buttonContent
);
}

const mergedTooltipCopyable: ConnectButtonTooltipProps['copyable'] =
typeof tooltip === 'object' ? tooltip.copyable !== false : !!tooltip;

let tooltipTitle: string = tooltip && account?.address ? fillWith0x(account?.address) : '';
if (typeof tooltip === 'object' && typeof tooltip.title === 'string') {
tooltipTitle = tooltip.title;
}
const ConnectButtonTooltipProps: () => ConnectButtonTooltipProps & { intl: IntlType } = () => {
shanchuan1 marked this conversation as resolved.
Show resolved Hide resolved
const mergedTooltipCopyable: ConnectButtonTooltipProps['copyable'] =
typeof tooltip === 'object' ? tooltip.copyable !== false : !!tooltip;
return {
intl,
copyable: mergedTooltipCopyable,
title: tooltipTitle,
prefixCls,
__hashId__: hashId,
...(typeof tooltip === 'object' ? tooltip : {}),
};
};

const main = (
<>
{contextHolder}
{tooltipTitle ? (
<ConnectButtonTooltip
intl={intl}
copyable={mergedTooltipCopyable}
title={tooltipTitle}
prefixCls={prefixCls}
__hashId__={hashId}
{...(typeof tooltip === 'object' ? tooltip : {})}
>
{content}
</ConnectButtonTooltip>
<ConnectButtonTooltip {...ConnectButtonTooltipProps()}>{content}</ConnectButtonTooltip>
) : (
content
)}
{profileModalContent}
<ProfileModal {...profileModalProps} />
</>
);

Expand Down
38 changes: 20 additions & 18 deletions packages/web3/src/connect-button/profile-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { useContext } from 'react';
import { Address } from '@ant-design/web3';
import type { Balance } from '@ant-design/web3-common';
import { Avatar, Button, ConfigProvider, message, Modal, Space, type AvatarProps } from 'antd';
import type { ModalProps } from 'antd';
import { Avatar, Button, ConfigProvider, message, Modal, Space } from 'antd';
import type { AvatarProps, ModalProps } from 'antd';
import classNames from 'classnames';

import { CryptoPrice } from '../crypto-price';
Expand Down Expand Up @@ -41,26 +41,28 @@ export const ProfileModal: React.FC<ProfileModalProps> = ({
const prefixCls = getPrefixCls('web3-connect-button-profile-modal');
const [messageApi, contextHolder] = message.useMessage();

const footer = (
<div className={classNames(`${prefixCls}-footer`, __hashId__)}>
{address ? (
<Button
onClick={() => {
writeCopyText(address).then(() => {
messageApi.success(intl.getMessage(intl.messages.addressCopied));
});
}}
>
{intl.getMessage(intl.messages.copyAddress)}
</Button>
) : null}
<Button onClick={onDisconnect}>{intl.getMessage(intl.messages.disconnect)}</Button>
</div>
);

return (
<>
{contextHolder}
<Modal
footer={
<div className={classNames(`${prefixCls}-footer`, __hashId__)}>
{address ? (
<Button
onClick={() => {
writeCopyText(address).then(() => {
messageApi.success(intl.getMessage(intl.messages.addressCopied));
});
}}
>
{intl.getMessage(intl.messages.copyAddress)}
</Button>
) : null}
<Button onClick={onDisconnect}>{intl.getMessage(intl.messages.disconnect)}</Button>
</div>
}
footer={footer}
width={280}
{...modalProps}
onCancel={onClose}
Expand Down
Loading