@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openzeppelin/ui-builder-adapter-evm",
3
- "version": "1.2.0",
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.2",
41
- "@openzeppelin/ui-react": "^1.0.0",
42
- "@openzeppelin/ui-types": "^1.1.0",
43
- "@openzeppelin/ui-utils": "^1.0.0",
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> = ({ className }) => {
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 className={className} />
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<{ className?: string }> = ({ className }) => {
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="flex flex-col">
36
- <span className="text-xs font-medium">{truncateMiddle(address, 4, 4)}</span>
37
- <span className="text-[9px] text-muted-foreground -mt-0.5">
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="ghost"
62
+ variant={variant || 'ghost'}
44
63
  size="icon"
45
- className="size-6 p-0"
64
+ className={cn(sizeProps.iconButtonSize, 'p-0')}
46
65
  title="Disconnect wallet"
47
66
  >
48
- <LogOut className="size-3.5" />
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 disabled={true} variant="outline" size="sm" className="h-8 px-2 text-xs">
30
- <Wallet className="size-3.5 mr-1" />
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="outline"
101
- size="sm"
102
- className="h-8 px-2 text-xs"
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="size-3.5 animate-spin mr-1" />
123
+ <Loader2 className={cn(sizeProps.iconSize, 'animate-spin mr-1')} />
107
124
  ) : (
108
- <Wallet className="size-3.5 mr-1" />
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 { cn } from '@openzeppelin/ui-utils';
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> = ({ className }) => {
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 className={className} />
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<{ className?: string }> = ({ className }) => {
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 className="h-8 text-xs px-2 min-w-[90px] max-w-[120px]">
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 key={chain.id} value={chain.id.toString()} className="text-xs py-1.5">
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-xs text-muted-foreground ml-2">
83
- <Loader2 className="h-3 w-3 animate-spin" />
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="outline"
86
- size="sm"
87
- className={cn('h-8 px-2 text-xs', props.className)}
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="h-3.5 w-3.5 animate-spin mr-1.5" />
91
+ <Loader2 className={cn(sizeProps.iconSize, 'animate-spin mr-1.5')} />
90
92
  {message}
91
93
  </Button>
92
94
  );