or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# Radix UI React Toggle

1

2

Radix UI React Toggle is a fully accessible two-state button component that can be pressed/unpressed. Built on Radix UI's primitive foundation, it provides comprehensive accessibility features, keyboard navigation, and flexible state management patterns for React applications.

3

4

## Package Information

5

6

- **Package Name**: @radix-ui/react-toggle

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install @radix-ui/react-toggle`

10

- **Peer Dependencies**: React 16.8+ (`npm install react@^16.8.0`)

11

12

## Core Imports

13

14

```typescript

15

import { Toggle, Root } from "@radix-ui/react-toggle";

16

import type { ToggleProps } from "@radix-ui/react-toggle";

17

```

18

19

For CommonJS:

20

21

```javascript

22

const { Toggle, Root } = require("@radix-ui/react-toggle");

23

```

24

25

## Basic Usage

26

27

```typescript

28

import { Toggle } from "@radix-ui/react-toggle";

29

30

// Uncontrolled toggle with default state

31

function BasicToggle() {

32

return (

33

<Toggle defaultPressed={false} onPressedChange={(pressed) => console.log(pressed)}>

34

Toggle Me

35

</Toggle>

36

);

37

}

38

39

// Controlled toggle

40

function ControlledToggle() {

41

const [isPressed, setIsPressed] = useState(false);

42

43

return (

44

<Toggle pressed={isPressed} onPressedChange={setIsPressed}>

45

{isPressed ? "On" : "Off"}

46

</Toggle>

47

);

48

}

49

```

50

51

## Architecture

52

53

The Toggle component provides a clean, accessible interface for two-state interactions:

54

55

- **HTML Button Foundation**: Built on semantic button elements for maximum compatibility

56

- **State Management**: Supports both controlled and uncontrolled component patterns

57

- **Event Handling**: Proper event composition and disabled state management

58

- **Accessibility**: Automatic ARIA attributes and semantic data attributes

59

- **Composition**: Supports `asChild` prop for flexible element composition

60

61

## Capabilities

62

63

### Toggle Component

64

65

The main toggle component that renders as a button with press/unpress functionality.

66

67

```typescript { .api }

68

/**

69

* Toggle component - A two-state button that can be pressed/unpressed

70

*/

71

const Toggle: React.ForwardRefExoticComponent<

72

ToggleProps & React.RefAttributes<HTMLButtonElement>

73

>;

74

75

/**

76

* Root component - Alias for Toggle following Radix UI naming conventions

77

*/

78

const Root: React.ForwardRefExoticComponent<

79

ToggleProps & React.RefAttributes<HTMLButtonElement>

80

>;

81

```

82

83

**Usage Examples:**

84

85

```typescript

86

// Basic uncontrolled usage

87

<Toggle defaultPressed onPressedChange={(pressed) => console.log(pressed)}>

88

Like

89

</Toggle>

90

91

// Controlled usage

92

<Toggle pressed={isPressed} onPressedChange={setIsPressed}>

93

{isPressed ? "Liked" : "Like"}

94

</Toggle>

95

96

// With custom styling via data attributes

97

<Toggle

98

className="toggle-button"

99

data-testid="like-button"

100

>

101

<HeartIcon />

102

</Toggle>

103

104

// Using asChild for custom element

105

<Toggle asChild>

106

<button className="custom-toggle-button">

107

Custom Toggle

108

</button>

109

</Toggle>

110

111

// Using Root alias

112

<Toggle.Root pressed={isPressed}>

113

Toggle Content

114

</Toggle.Root>

115

```

116

117

### Toggle Props Interface

118

119

Complete props interface extending standard HTML button attributes.

120

121

```typescript { .api }

122

interface ToggleProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {

123

/**

124

* The controlled state of the toggle

125

*/

126

pressed?: boolean;

127

128

/**

129

* The state of the toggle when initially rendered

130

* Use when you do not need to control the state

131

* @defaultValue false

132

*/

133

defaultPressed?: boolean;

134

135

/**

136

* Callback that fires when the state of the toggle changes

137

*/

138

onPressedChange?: (pressed: boolean) => void;

139

140

/**

141

* When true, merges props into the child element instead of rendering a button

142

* Enables the slot pattern for custom element composition

143

*/

144

asChild?: boolean;

145

146

/**

147

* All standard HTML button attributes are supported:

148

* - Event handlers: onClick, onMouseDown, onMouseUp, onDoubleClick, etc.

149

* - Form attributes: type, disabled, form, name, value, etc.

150

* - Accessibility: aria-*, role, tabIndex, etc.

151

* - Styling: className, style, data-*, etc.

152

* - Standard attributes: id, title, lang, dir, etc.

153

*/

154

}

155

```

156

157

158

## State Management Patterns

159

160

### Controlled Pattern

161

162

When you need to manage the toggle state externally:

163

164

```typescript

165

function ControlledExample() {

166

const [isPressed, setIsPressed] = useState(false);

167

168

// External state updates

169

useEffect(() => {

170

if (someCondition) {

171

setIsPressed(true);

172

}

173

}, [someCondition]);

174

175

return (

176

<Toggle

177

pressed={isPressed}

178

onPressedChange={setIsPressed}

179

>

180

{isPressed ? "Active" : "Inactive"}

181

</Toggle>

182

);

183

}

184

```

185

186

### Uncontrolled Pattern

187

188

When the toggle manages its own state internally:

189

190

```typescript

191

function UncontrolledExample() {

192

return (

193

<Toggle

194

defaultPressed={false}

195

onPressedChange={(pressed) => {

196

// React to state changes without controlling the state

197

console.log("Toggle is now:", pressed ? "pressed" : "unpressed");

198

}}

199

>

200

Toggle Me

201

</Toggle>

202

);

203

}

204

```

205

206

## Accessibility Features

207

208

The Toggle component provides comprehensive accessibility features:

209

210

### ARIA Attributes (Automatic)

211

212

```typescript

213

// When pressed=false or unpressed

214

<button aria-pressed="false" data-state="off">...</button>

215

216

// When pressed=true or pressed

217

<button aria-pressed="true" data-state="on">...</button>

218

219

// When disabled

220

<button disabled data-disabled="">...</button>

221

```

222

223

### Keyboard Navigation

224

225

- **Space Key**: Toggles the pressed state

226

- **Enter Key**: Toggles the pressed state (standard button behavior)

227

- **Tab Navigation**: Follows standard focus order

228

- **Focus Management**: Proper focus handling when disabled

229

230

### Screen Reader Support

231

232

- Announces current state via `aria-pressed` attribute

233

- Compatible with all major screen readers

234

- Proper role semantics as a toggle button

235

236

## Data Attributes for Styling

237

238

The component automatically applies data attributes for CSS styling:

239

240

```css

241

/* Target different states */

242

.toggle-button[data-state="on"] {

243

background-color: blue;

244

color: white;

245

}

246

247

.toggle-button[data-state="off"] {

248

background-color: gray;

249

color: black;

250

}

251

252

.toggle-button[data-disabled] {

253

opacity: 0.5;

254

cursor: not-allowed;

255

}

256

```

257

258

## Advanced Usage

259

260

### Custom Element Composition (asChild)

261

262

Use the `asChild` prop to merge toggle functionality into custom elements:

263

264

```typescript

265

function CustomToggle() {

266

return (

267

<Toggle asChild pressed={isPressed} onPressedChange={setIsPressed}>

268

<div className="custom-toggle-div" role="button" tabIndex={0}>

269

<Icon name={isPressed ? "heart-filled" : "heart-outline"} />

270

<span>{isPressed ? "Liked" : "Like"}</span>

271

</div>

272

</Toggle>

273

);

274

}

275

```

276

277

### Event Handler Composition

278

279

Toggle properly composes event handlers when extending functionality:

280

281

```typescript

282

function EnhancedToggle() {

283

const handleClick = (event) => {

284

console.log("Custom click handler");

285

// Toggle's internal handler will still run unless preventDefault() is called

286

};

287

288

return (

289

<Toggle

290

onClick={handleClick}

291

onPressedChange={(pressed) => console.log("State changed:", pressed)}

292

>

293

Enhanced Toggle

294

</Toggle>

295

);

296

}

297

```

298

299

### Form Integration

300

301

Toggle works seamlessly with forms:

302

303

```typescript

304

function FormToggle() {

305

return (

306

<form>

307

<Toggle

308

name="notifications"

309

value="enabled"

310

defaultPressed

311

onPressedChange={(pressed) => {

312

// Update form state or trigger validation

313

}}

314

>

315

Enable Notifications

316

</Toggle>

317

</form>

318

);

319

}

320

```

321

322

## Types

323

324

```typescript { .api }

325

/**

326

* Complete props interface for Toggle component

327

*/

328

interface ToggleProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {

329

pressed?: boolean;

330

defaultPressed?: boolean;

331

onPressedChange?: (pressed: boolean) => void;

332

asChild?: boolean;

333

}

334

```