@openzeppelin/ui-builder-adapter-evm 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +106 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +114 -35
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/src/wallet/components/account/AccountDisplay.tsx +30 -11
- package/src/wallet/components/connect/ConnectButton.tsx +29 -12
- package/src/wallet/components/network/NetworkSwitcher.tsx +41 -9
- package/src/wallet/rainbowkit/components.tsx +7 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openzeppelin/ui-builder-adapter-evm",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "EVM Adapter for UI Builder",
|
|
6
6
|
"keywords": [
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@openzeppelin/relayer-sdk": "1.4.0",
|
|
40
|
-
"@openzeppelin/ui-components": "^1.0.
|
|
41
|
-
"@openzeppelin/ui-react": "^1.
|
|
42
|
-
"@openzeppelin/ui-types": "^1.
|
|
43
|
-
"@openzeppelin/ui-utils": "^1.
|
|
40
|
+
"@openzeppelin/ui-components": "^1.0.4",
|
|
41
|
+
"@openzeppelin/ui-react": "^1.1.0",
|
|
42
|
+
"@openzeppelin/ui-types": "^1.2.0",
|
|
43
|
+
"@openzeppelin/ui-utils": "^1.1.0",
|
|
44
44
|
"@wagmi/connectors": "5.7.13",
|
|
45
45
|
"@wagmi/core": "^2.20.3",
|
|
46
46
|
"@web3icons/react": "^4.0.19",
|
|
@@ -4,7 +4,7 @@ import React from 'react';
|
|
|
4
4
|
import { Button } from '@openzeppelin/ui-components';
|
|
5
5
|
import { useDerivedAccountStatus, useDerivedDisconnect } from '@openzeppelin/ui-react';
|
|
6
6
|
import type { BaseComponentProps } from '@openzeppelin/ui-types';
|
|
7
|
-
import { cn, truncateMiddle } from '@openzeppelin/ui-utils';
|
|
7
|
+
import { cn, getWalletAccountDisplaySizeProps, truncateMiddle } from '@openzeppelin/ui-utils';
|
|
8
8
|
|
|
9
9
|
import { SafeWagmiComponent } from '../../utils/SafeWagmiComponent';
|
|
10
10
|
|
|
@@ -12,40 +12,59 @@ import { SafeWagmiComponent } from '../../utils/SafeWagmiComponent';
|
|
|
12
12
|
* A component that displays the connected account address and chain ID.
|
|
13
13
|
* Also includes a disconnect button.
|
|
14
14
|
*/
|
|
15
|
-
export const CustomAccountDisplay: React.FC<BaseComponentProps> = ({
|
|
15
|
+
export const CustomAccountDisplay: React.FC<BaseComponentProps> = ({
|
|
16
|
+
className,
|
|
17
|
+
size,
|
|
18
|
+
variant,
|
|
19
|
+
fullWidth,
|
|
20
|
+
}) => {
|
|
16
21
|
// Use the SafeWagmiComponent with null fallback
|
|
17
22
|
return (
|
|
18
23
|
<SafeWagmiComponent fallback={null}>
|
|
19
|
-
<AccountDisplayContent
|
|
24
|
+
<AccountDisplayContent
|
|
25
|
+
className={className}
|
|
26
|
+
size={size}
|
|
27
|
+
variant={variant}
|
|
28
|
+
fullWidth={fullWidth}
|
|
29
|
+
/>
|
|
20
30
|
</SafeWagmiComponent>
|
|
21
31
|
);
|
|
22
32
|
};
|
|
23
33
|
|
|
24
34
|
// Inner component that uses derived hooks
|
|
25
|
-
const AccountDisplayContent: React.FC<
|
|
35
|
+
const AccountDisplayContent: React.FC<BaseComponentProps> = ({
|
|
36
|
+
className,
|
|
37
|
+
size,
|
|
38
|
+
variant,
|
|
39
|
+
fullWidth,
|
|
40
|
+
}) => {
|
|
26
41
|
const { isConnected, address, chainId } = useDerivedAccountStatus();
|
|
27
42
|
const { disconnect } = useDerivedDisconnect();
|
|
28
43
|
|
|
44
|
+
const sizeProps = getWalletAccountDisplaySizeProps(size);
|
|
45
|
+
|
|
29
46
|
if (!isConnected || !address || !disconnect) {
|
|
30
47
|
return null;
|
|
31
48
|
}
|
|
32
49
|
|
|
33
50
|
return (
|
|
34
|
-
<div className={cn('flex items-center gap-2', className)}>
|
|
35
|
-
<div className=
|
|
36
|
-
<span className=
|
|
37
|
-
|
|
51
|
+
<div className={cn('flex items-center gap-2', fullWidth && 'w-full', className)}>
|
|
52
|
+
<div className={cn('flex flex-col', fullWidth && 'flex-1')}>
|
|
53
|
+
<span className={cn(sizeProps.textSize, 'font-medium')}>
|
|
54
|
+
{truncateMiddle(address, 4, 4)}
|
|
55
|
+
</span>
|
|
56
|
+
<span className={cn(sizeProps.subTextSize, 'text-muted-foreground -mt-0.5')}>
|
|
38
57
|
{chainId ? `Chain ID: ${chainId}` : 'Chain ID: N/A'}
|
|
39
58
|
</span>
|
|
40
59
|
</div>
|
|
41
60
|
<Button
|
|
42
61
|
onClick={() => disconnect()}
|
|
43
|
-
variant=
|
|
62
|
+
variant={variant || 'ghost'}
|
|
44
63
|
size="icon"
|
|
45
|
-
className=
|
|
64
|
+
className={cn(sizeProps.iconButtonSize, 'p-0')}
|
|
46
65
|
title="Disconnect wallet"
|
|
47
66
|
>
|
|
48
|
-
<LogOut className=
|
|
67
|
+
<LogOut className={sizeProps.iconSize} />
|
|
49
68
|
</Button>
|
|
50
69
|
</div>
|
|
51
70
|
);
|
|
@@ -3,8 +3,8 @@ import React, { useEffect, useState } from 'react';
|
|
|
3
3
|
|
|
4
4
|
import { Button } from '@openzeppelin/ui-components';
|
|
5
5
|
import { useDerivedAccountStatus, useDerivedConnectStatus } from '@openzeppelin/ui-react';
|
|
6
|
-
import type { BaseComponentProps } from '@openzeppelin/ui-types';
|
|
7
|
-
import { cn } from '@openzeppelin/ui-utils';
|
|
6
|
+
import type { BaseComponentProps, WalletComponentSize } from '@openzeppelin/ui-types';
|
|
7
|
+
import { cn, getWalletButtonSizeProps } from '@openzeppelin/ui-utils';
|
|
8
8
|
|
|
9
9
|
import { SafeWagmiComponent } from '../../utils/SafeWagmiComponent';
|
|
10
10
|
import { ConnectorDialog } from './ConnectorDialog';
|
|
@@ -20,14 +20,23 @@ export interface ConnectButtonProps extends BaseComponentProps {
|
|
|
20
20
|
|
|
21
21
|
export const CustomConnectButton: React.FC<ConnectButtonProps> = ({
|
|
22
22
|
className,
|
|
23
|
+
size,
|
|
24
|
+
variant,
|
|
25
|
+
fullWidth,
|
|
23
26
|
hideWhenConnected = true,
|
|
24
27
|
}) => {
|
|
25
28
|
const [dialogOpen, setDialogOpen] = useState(false);
|
|
29
|
+
const sizeProps = getWalletButtonSizeProps(size);
|
|
26
30
|
|
|
27
31
|
const unavailableButton = (
|
|
28
|
-
<div className={cn('flex items-center', className)}>
|
|
29
|
-
<Button
|
|
30
|
-
|
|
32
|
+
<div className={cn('flex items-center', fullWidth && 'w-full', className)}>
|
|
33
|
+
<Button
|
|
34
|
+
disabled={true}
|
|
35
|
+
variant={variant || 'outline'}
|
|
36
|
+
size={sizeProps.size}
|
|
37
|
+
className={cn(sizeProps.className, fullWidth && 'w-full')}
|
|
38
|
+
>
|
|
39
|
+
<Wallet className={cn(sizeProps.iconSize, 'mr-1')} />
|
|
31
40
|
Wallet Unavailable
|
|
32
41
|
</Button>
|
|
33
42
|
</div>
|
|
@@ -37,6 +46,9 @@ export const CustomConnectButton: React.FC<ConnectButtonProps> = ({
|
|
|
37
46
|
<SafeWagmiComponent fallback={unavailableButton}>
|
|
38
47
|
<ConnectButtonContent
|
|
39
48
|
className={className}
|
|
49
|
+
size={size}
|
|
50
|
+
variant={variant}
|
|
51
|
+
fullWidth={fullWidth}
|
|
40
52
|
dialogOpen={dialogOpen}
|
|
41
53
|
setDialogOpen={setDialogOpen}
|
|
42
54
|
hideWhenConnected={hideWhenConnected}
|
|
@@ -47,16 +59,21 @@ export const CustomConnectButton: React.FC<ConnectButtonProps> = ({
|
|
|
47
59
|
|
|
48
60
|
const ConnectButtonContent: React.FC<{
|
|
49
61
|
className?: string;
|
|
62
|
+
size?: WalletComponentSize;
|
|
63
|
+
variant?: BaseComponentProps['variant'];
|
|
64
|
+
fullWidth?: boolean;
|
|
50
65
|
dialogOpen: boolean;
|
|
51
66
|
setDialogOpen: (open: boolean) => void;
|
|
52
67
|
hideWhenConnected: boolean;
|
|
53
|
-
}> = ({ className, dialogOpen, setDialogOpen, hideWhenConnected }) => {
|
|
68
|
+
}> = ({ className, size, variant, fullWidth, dialogOpen, setDialogOpen, hideWhenConnected }) => {
|
|
54
69
|
const { isConnected } = useDerivedAccountStatus();
|
|
55
70
|
const { isConnecting: isHookConnecting, error: connectError } = useDerivedConnectStatus();
|
|
56
71
|
|
|
57
72
|
// Local state to indicate the button has been clicked and dialog is open, awaiting user selection
|
|
58
73
|
const [isManuallyInitiated, setIsManuallyInitiated] = useState(false);
|
|
59
74
|
|
|
75
|
+
const sizeProps = getWalletButtonSizeProps(size);
|
|
76
|
+
|
|
60
77
|
useEffect(() => {
|
|
61
78
|
if (isConnected && hideWhenConnected) {
|
|
62
79
|
setDialogOpen(false);
|
|
@@ -93,19 +110,19 @@ const ConnectButtonContent: React.FC<{
|
|
|
93
110
|
const showButtonLoading = isHookConnecting || isManuallyInitiated;
|
|
94
111
|
|
|
95
112
|
return (
|
|
96
|
-
<div className={cn('flex items-center', className)}>
|
|
113
|
+
<div className={cn('flex items-center', fullWidth && 'w-full', className)}>
|
|
97
114
|
<Button
|
|
98
115
|
onClick={handleConnectClick}
|
|
99
116
|
disabled={showButtonLoading || isConnected}
|
|
100
|
-
variant=
|
|
101
|
-
size=
|
|
102
|
-
className=
|
|
117
|
+
variant={variant || 'outline'}
|
|
118
|
+
size={sizeProps.size}
|
|
119
|
+
className={cn(sizeProps.className, fullWidth && 'w-full')}
|
|
103
120
|
title={isConnected ? 'Connected' : connectError?.message || 'Connect Wallet'}
|
|
104
121
|
>
|
|
105
122
|
{showButtonLoading ? (
|
|
106
|
-
<Loader2 className=
|
|
123
|
+
<Loader2 className={cn(sizeProps.iconSize, 'animate-spin mr-1')} />
|
|
107
124
|
) : (
|
|
108
|
-
<Wallet className=
|
|
125
|
+
<Wallet className={cn(sizeProps.iconSize, 'mr-1')} />
|
|
109
126
|
)}
|
|
110
127
|
{showButtonLoading ? 'Connecting...' : 'Connect Wallet'}
|
|
111
128
|
</Button>
|
|
@@ -15,7 +15,11 @@ import {
|
|
|
15
15
|
useDerivedSwitchChainStatus,
|
|
16
16
|
} from '@openzeppelin/ui-react';
|
|
17
17
|
import type { BaseComponentProps } from '@openzeppelin/ui-types';
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
cn,
|
|
20
|
+
getWalletNetworkSwitcherSizeProps,
|
|
21
|
+
getWalletNetworkSwitcherVariantClassName,
|
|
22
|
+
} from '@openzeppelin/ui-utils';
|
|
19
23
|
|
|
20
24
|
import { SafeWagmiComponent } from '../../utils/SafeWagmiComponent';
|
|
21
25
|
|
|
@@ -23,21 +27,39 @@ import { SafeWagmiComponent } from '../../utils/SafeWagmiComponent';
|
|
|
23
27
|
* A component that displays the current network and allows switching to other networks.
|
|
24
28
|
* Uses the chainId and switchChain hooks from wagmi.
|
|
25
29
|
*/
|
|
26
|
-
export const CustomNetworkSwitcher: React.FC<BaseComponentProps> = ({
|
|
30
|
+
export const CustomNetworkSwitcher: React.FC<BaseComponentProps> = ({
|
|
31
|
+
className,
|
|
32
|
+
size,
|
|
33
|
+
variant,
|
|
34
|
+
fullWidth,
|
|
35
|
+
}) => {
|
|
27
36
|
// Use the SafeWagmiComponent with null fallback
|
|
28
37
|
return (
|
|
29
38
|
<SafeWagmiComponent fallback={null}>
|
|
30
|
-
<NetworkSwitcherContent
|
|
39
|
+
<NetworkSwitcherContent
|
|
40
|
+
className={className}
|
|
41
|
+
size={size}
|
|
42
|
+
variant={variant}
|
|
43
|
+
fullWidth={fullWidth}
|
|
44
|
+
/>
|
|
31
45
|
</SafeWagmiComponent>
|
|
32
46
|
);
|
|
33
47
|
};
|
|
34
48
|
|
|
35
49
|
// Inner component that uses wagmi hooks
|
|
36
|
-
const NetworkSwitcherContent: React.FC<
|
|
50
|
+
const NetworkSwitcherContent: React.FC<BaseComponentProps> = ({
|
|
51
|
+
className,
|
|
52
|
+
size,
|
|
53
|
+
variant,
|
|
54
|
+
fullWidth,
|
|
55
|
+
}) => {
|
|
37
56
|
const { isConnected } = useDerivedAccountStatus();
|
|
38
57
|
const { currentChainId, availableChains: unknownChains } = useDerivedChainInfo();
|
|
39
58
|
const { switchChain, isSwitching: isPending, error } = useDerivedSwitchChainStatus();
|
|
40
59
|
|
|
60
|
+
const sizeProps = getWalletNetworkSwitcherSizeProps(size);
|
|
61
|
+
const variantClassName = getWalletNetworkSwitcherVariantClassName(variant);
|
|
62
|
+
|
|
41
63
|
// Cast to Chain[] for use within this EVM-specific component
|
|
42
64
|
const typedAvailableChains = unknownChains as Chain[];
|
|
43
65
|
|
|
@@ -55,13 +77,19 @@ const NetworkSwitcherContent: React.FC<{ className?: string }> = ({ className })
|
|
|
55
77
|
const currentChainName = currentChain?.name || 'Network';
|
|
56
78
|
|
|
57
79
|
return (
|
|
58
|
-
<div className={cn('flex items-center', className)}>
|
|
80
|
+
<div className={cn('flex items-center', fullWidth && 'w-full', className)}>
|
|
59
81
|
<Select
|
|
60
82
|
value={currentChainId?.toString() ?? ''}
|
|
61
83
|
onValueChange={(value: string) => handleNetworkChange(Number(value))}
|
|
62
84
|
disabled={isPending || typedAvailableChains.length === 0}
|
|
63
85
|
>
|
|
64
|
-
<SelectTrigger
|
|
86
|
+
<SelectTrigger
|
|
87
|
+
className={cn(
|
|
88
|
+
sizeProps.triggerClassName,
|
|
89
|
+
variantClassName,
|
|
90
|
+
fullWidth && 'w-full max-w-none'
|
|
91
|
+
)}
|
|
92
|
+
>
|
|
65
93
|
<SelectValue placeholder="Network">{currentChainName}</SelectValue>
|
|
66
94
|
</SelectTrigger>
|
|
67
95
|
<SelectContent
|
|
@@ -71,7 +99,11 @@ const NetworkSwitcherContent: React.FC<{ className?: string }> = ({ className })
|
|
|
71
99
|
className="w-auto min-w-[160px] max-h-[300px]"
|
|
72
100
|
>
|
|
73
101
|
{typedAvailableChains.map((chain) => (
|
|
74
|
-
<SelectItem
|
|
102
|
+
<SelectItem
|
|
103
|
+
key={chain.id}
|
|
104
|
+
value={chain.id.toString()}
|
|
105
|
+
className={sizeProps.itemClassName}
|
|
106
|
+
>
|
|
75
107
|
{chain.name}
|
|
76
108
|
</SelectItem>
|
|
77
109
|
))}
|
|
@@ -79,8 +111,8 @@ const NetworkSwitcherContent: React.FC<{ className?: string }> = ({ className })
|
|
|
79
111
|
</Select>
|
|
80
112
|
|
|
81
113
|
{isPending && (
|
|
82
|
-
<span className="text-
|
|
83
|
-
<Loader2 className=
|
|
114
|
+
<span className="text-muted-foreground ml-2">
|
|
115
|
+
<Loader2 className={cn(sizeProps.loaderSize, 'animate-spin')} />
|
|
84
116
|
</span>
|
|
85
117
|
)}
|
|
86
118
|
|
|
@@ -3,7 +3,7 @@ import React, { useContext, useEffect, useRef, useState } from 'react';
|
|
|
3
3
|
|
|
4
4
|
import { Button } from '@openzeppelin/ui-components';
|
|
5
5
|
import type { BaseComponentProps } from '@openzeppelin/ui-types';
|
|
6
|
-
import { cn, logger } from '@openzeppelin/ui-utils';
|
|
6
|
+
import { cn, getWalletButtonSizeProps, logger } from '@openzeppelin/ui-utils';
|
|
7
7
|
|
|
8
8
|
import { CustomConnectButton } from '../components';
|
|
9
9
|
import { WagmiProviderInitializedContext } from '../context/wagmi-context';
|
|
@@ -79,14 +79,16 @@ export const RainbowKitConnectButton: React.FC<BaseComponentProps> = (props) =>
|
|
|
79
79
|
};
|
|
80
80
|
}, []); // Effect for dynamic import runs once
|
|
81
81
|
|
|
82
|
+
const sizeProps = getWalletButtonSizeProps(props.size);
|
|
83
|
+
|
|
82
84
|
const renderLoadingPlaceholder = (message: string) => (
|
|
83
85
|
<Button
|
|
84
86
|
disabled={true}
|
|
85
|
-
variant=
|
|
86
|
-
size=
|
|
87
|
-
className={cn(
|
|
87
|
+
variant={props.variant || 'outline'}
|
|
88
|
+
size={sizeProps.size}
|
|
89
|
+
className={cn(sizeProps.className, props.fullWidth && 'w-full', props.className)}
|
|
88
90
|
>
|
|
89
|
-
<Loader2 className=
|
|
91
|
+
<Loader2 className={cn(sizeProps.iconSize, 'animate-spin mr-1.5')} />
|
|
90
92
|
{message}
|
|
91
93
|
</Button>
|
|
92
94
|
);
|