0
# Modal Controls
1
2
React hooks for programmatically controlling wallet connection, account, and chain selection modals.
3
4
## Capabilities
5
6
### useConnectModal
7
8
Hook for controlling the wallet connection modal programmatically.
9
10
```typescript { .api }
11
/**
12
* Hook for controlling the wallet connection modal
13
* @returns Object with modal state and control function
14
*/
15
function useConnectModal(): {
16
connectModalOpen: boolean;
17
openConnectModal?: () => void;
18
};
19
```
20
21
**Usage Examples:**
22
23
```typescript
24
import { useConnectModal } from '@rainbow-me/rainbowkit';
25
26
function CustomConnectButton() {
27
const { openConnectModal, connectModalOpen } = useConnectModal();
28
29
return (
30
<button
31
onClick={openConnectModal}
32
disabled={!openConnectModal || connectModalOpen}
33
>
34
{connectModalOpen ? 'Connecting...' : 'Connect Wallet'}
35
</button>
36
);
37
}
38
```
39
40
### useAccountModal
41
42
Hook for controlling the account management modal programmatically.
43
44
```typescript { .api }
45
/**
46
* Hook for controlling the account management modal
47
* @returns Object with modal state and control function
48
*/
49
function useAccountModal(): {
50
accountModalOpen: boolean;
51
openAccountModal?: () => void;
52
};
53
```
54
55
**Usage Examples:**
56
57
```typescript
58
import { useAccountModal } from '@rainbow-me/rainbowkit';
59
import { useAccount } from 'wagmi';
60
61
function AccountButton() {
62
const { openAccountModal, accountModalOpen } = useAccountModal();
63
const { address, isConnected } = useAccount();
64
65
if (!isConnected) return null;
66
67
return (
68
<button
69
onClick={openAccountModal}
70
disabled={!openAccountModal || accountModalOpen}
71
>
72
{address?.slice(0, 6)}...{address?.slice(-4)}
73
</button>
74
);
75
}
76
```
77
78
### useChainModal
79
80
Hook for controlling the chain/network selection modal programmatically.
81
82
```typescript { .api }
83
/**
84
* Hook for controlling the chain selection modal
85
* @returns Object with modal state and control function
86
*/
87
function useChainModal(): {
88
chainModalOpen: boolean;
89
openChainModal?: () => void;
90
};
91
```
92
93
**Usage Examples:**
94
95
```typescript
96
import { useChainModal } from '@rainbow-me/rainbowkit';
97
import { useNetwork } from 'wagmi';
98
99
function ChainSelector() {
100
const { openChainModal, chainModalOpen } = useChainModal();
101
const { chain } = useNetwork();
102
103
return (
104
<button
105
onClick={openChainModal}
106
disabled={!openChainModal || chainModalOpen}
107
>
108
{chain?.name ?? 'Unknown Chain'}
109
</button>
110
);
111
}
112
```
113
114
### useModalState
115
116
Hook for accessing the state of all modals simultaneously.
117
118
```typescript { .api }
119
/**
120
* Hook for accessing the state of all modals
121
* @returns Object with all modal states
122
*/
123
function useModalState(): {
124
accountModalOpen: boolean;
125
chainModalOpen: boolean;
126
connectModalOpen: boolean;
127
};
128
```
129
130
**Usage Examples:**
131
132
```typescript
133
import { useModalState } from '@rainbow-me/rainbowkit';
134
135
function ModalStateIndicator() {
136
const { accountModalOpen, chainModalOpen, connectModalOpen } = useModalState();
137
138
const anyModalOpen = accountModalOpen || chainModalOpen || connectModalOpen;
139
140
return (
141
<div>
142
<p>Modal Status: {anyModalOpen ? 'Open' : 'Closed'}</p>
143
{connectModalOpen && <p>Connect modal is open</p>}
144
{accountModalOpen && <p>Account modal is open</p>}
145
{chainModalOpen && <p>Chain modal is open</p>}
146
</div>
147
);
148
}
149
```
150
151
## Advanced Usage Patterns
152
153
### Custom Modal Trigger Components
154
155
```typescript
156
import {
157
useConnectModal,
158
useAccountModal,
159
useChainModal
160
} from '@rainbow-me/rainbowkit';
161
import { useAccount, useNetwork } from 'wagmi';
162
163
function CustomWalletInterface() {
164
const { openConnectModal } = useConnectModal();
165
const { openAccountModal } = useAccountModal();
166
const { openChainModal } = useChainModal();
167
168
const { address, isConnected } = useAccount();
169
const { chain } = useNetwork();
170
171
if (!isConnected) {
172
return (
173
<button onClick={openConnectModal} className="connect-btn">
174
Connect Wallet
175
</button>
176
);
177
}
178
179
return (
180
<div className="wallet-interface">
181
<button onClick={openAccountModal} className="account-btn">
182
<span>π€</span>
183
<span>{address?.slice(0, 6)}...{address?.slice(-4)}</span>
184
</button>
185
186
<button onClick={openChainModal} className="chain-btn">
187
<span>π</span>
188
<span>{chain?.name ?? 'Unknown'}</span>
189
</button>
190
</div>
191
);
192
}
193
```
194
195
### Conditional Modal Opening
196
197
```typescript
198
import { useConnectModal, useChainModal } from '@rainbow-me/rainbowkit';
199
import { useAccount, useNetwork } from 'wagmi';
200
201
function SmartConnectButton() {
202
const { openConnectModal } = useConnectModal();
203
const { openChainModal } = useChainModal();
204
205
const { isConnected } = useAccount();
206
const { chain } = useNetwork();
207
208
const handleClick = () => {
209
if (!isConnected) {
210
openConnectModal?.();
211
} else if (chain?.unsupported) {
212
openChainModal?.();
213
}
214
};
215
216
const getButtonText = () => {
217
if (!isConnected) return 'Connect Wallet';
218
if (chain?.unsupported) return 'Switch Network';
219
return 'Connected';
220
};
221
222
return (
223
<button
224
onClick={handleClick}
225
disabled={isConnected && !chain?.unsupported}
226
>
227
{getButtonText()}
228
</button>
229
);
230
}
231
```
232
233
### Modal State-Based UI
234
235
```typescript
236
import { useModalState } from '@rainbow-me/rainbowkit';
237
238
function AppLayout({ children }) {
239
const { accountModalOpen, chainModalOpen, connectModalOpen } = useModalState();
240
241
const isAnyModalOpen = accountModalOpen || chainModalOpen || connectModalOpen;
242
243
return (
244
<div className={`app-layout ${isAnyModalOpen ? 'modal-active' : ''}`}>
245
{/* Overlay when modals are open */}
246
{isAnyModalOpen && <div className="modal-overlay" />}
247
248
<header>
249
<h1>My DApp</h1>
250
</header>
251
252
<main>
253
{children}
254
</main>
255
256
{/* Disable interactions when modals are open */}
257
<style jsx>{`
258
.app-layout.modal-active main {
259
pointer-events: none;
260
opacity: 0.8;
261
}
262
263
.modal-overlay {
264
position: fixed;
265
top: 0;
266
left: 0;
267
right: 0;
268
bottom: 0;
269
background: rgba(0, 0, 0, 0.3);
270
z-index: 999;
271
}
272
`}</style>
273
</div>
274
);
275
}
276
```
277
278
### Integration with Form Validation
279
280
```typescript
281
import { useConnectModal } from '@rainbow-me/rainbowkit';
282
import { useAccount } from 'wagmi';
283
import { useState } from 'react';
284
285
function TokenTransferForm() {
286
const { openConnectModal } = useConnectModal();
287
const { isConnected } = useAccount();
288
const [recipient, setRecipient] = useState('');
289
const [amount, setAmount] = useState('');
290
291
const handleSubmit = (e: React.FormEvent) => {
292
e.preventDefault();
293
294
if (!isConnected) {
295
openConnectModal?.();
296
return;
297
}
298
299
// Process transfer
300
console.log('Transferring', amount, 'to', recipient);
301
};
302
303
return (
304
<form onSubmit={handleSubmit}>
305
<input
306
type="text"
307
placeholder="Recipient address"
308
value={recipient}
309
onChange={(e) => setRecipient(e.target.value)}
310
required
311
/>
312
313
<input
314
type="number"
315
placeholder="Amount"
316
value={amount}
317
onChange={(e) => setAmount(e.target.value)}
318
required
319
/>
320
321
<button type="submit">
322
{isConnected ? 'Transfer' : 'Connect Wallet to Transfer'}
323
</button>
324
</form>
325
);
326
}
327
```