or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdconfiguration.mdcore-components.mdindex.mdmodal-controls.mdtheming.mdwallet-connectors.md

modal-controls.mddocs/

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

```