or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-button.mdindex.mdtoggle-button-groups.mdtoggle-button.md

toggle-button-groups.mddocs/

0

# Toggle Button Groups

1

2

Manages collections of toggle buttons with proper ARIA semantics, supporting both single and multiple selection modes. The group hooks provide container management and individual item behavior for toggle button collections.

3

4

## Capabilities

5

6

### useToggleButtonGroup Hook

7

8

Creates container behavior for toggle button groups with proper ARIA semantics.

9

10

```typescript { .api }

11

/**

12

* Provides container behavior for toggle button groups with proper ARIA semantics

13

* and keyboard navigation support.

14

*/

15

function useToggleButtonGroup(

16

props: AriaToggleButtonGroupProps,

17

state: ToggleGroupState,

18

ref: RefObject<HTMLElement | null>

19

): ToggleButtonGroupAria;

20

```

21

22

### useToggleButtonGroupItem Hook

23

24

Creates behavior for individual items within a toggle button group.

25

26

```typescript { .api }

27

/**

28

* Provides the behavior and accessibility implementation for a toggle button component

29

* within a toggle button group. Handles selection state coordination with the group.

30

*/

31

function useToggleButtonGroupItem(props: AriaToggleButtonGroupItemOptions<'button'>, state: ToggleGroupState, ref: RefObject<HTMLButtonElement | null>): ToggleButtonAria<ButtonHTMLAttributes<HTMLButtonElement>>;

32

function useToggleButtonGroupItem(props: AriaToggleButtonGroupItemOptions<'a'>, state: ToggleGroupState, ref: RefObject<HTMLAnchorElement | null>): ToggleButtonAria<AnchorHTMLAttributes<HTMLAnchorElement>>;

33

function useToggleButtonGroupItem(props: AriaToggleButtonGroupItemOptions<'div'>, state: ToggleGroupState, ref: RefObject<HTMLDivElement | null>): ToggleButtonAria<HTMLAttributes<HTMLDivElement>>;

34

function useToggleButtonGroupItem(props: AriaToggleButtonGroupItemOptions<'input'>, state: ToggleGroupState, ref: RefObject<HTMLInputElement | null>): ToggleButtonAria<InputHTMLAttributes<HTMLInputElement>>;

35

function useToggleButtonGroupItem(props: AriaToggleButtonGroupItemOptions<'span'>, state: ToggleGroupState, ref: RefObject<HTMLSpanElement | null>): ToggleButtonAria<HTMLAttributes<HTMLSpanElement>>;

36

function useToggleButtonGroupItem(props: AriaToggleButtonGroupItemOptions<ElementType>, state: ToggleGroupState, ref: RefObject<Element | null>): ToggleButtonAria<DOMAttributes>;

37

```

38

39

**Usage Examples:**

40

41

```typescript

42

import { useToggleButtonGroup, useToggleButtonGroupItem } from "@react-aria/button";

43

import { useToggleGroupState } from "@react-stately/toggle";

44

import { useRef } from "react";

45

46

// Basic toggle button group

47

function ToggleButtonGroup(props) {

48

let groupRef = useRef<HTMLDivElement | null>(null);

49

let state = useToggleGroupState(props);

50

let { groupProps } = useToggleButtonGroup(props, state, groupRef);

51

52

return (

53

<div {...groupProps} ref={groupRef}>

54

{props.children}

55

</div>

56

);

57

}

58

59

// Toggle button group item

60

function ToggleButtonGroupItem(props) {

61

let ref = useRef<HTMLButtonElement | null>(null);

62

let { buttonProps, isPressed, isSelected, isDisabled } = useToggleButtonGroupItem(

63

props,

64

props.state,

65

ref

66

);

67

68

return (

69

<button

70

{...buttonProps}

71

style={{

72

background: isPressed

73

? (isSelected ? 'darkblue' : 'gray')

74

: (isSelected ? 'blue' : 'lightgray'),

75

color: isSelected ? 'white' : 'black',

76

border: '1px solid #ccc',

77

padding: '8px 12px'

78

}}

79

ref={ref}>

80

{props.children}

81

</button>

82

);

83

}

84

85

// Complete toggle button group example

86

function TextAlignmentGroup() {

87

let groupRef = useRef<HTMLDivElement | null>(null);

88

let state = useToggleGroupState({

89

selectedKeys: ['center'],

90

selectionMode: 'single',

91

onChange: (selectedKeys) => {

92

console.log('Selected alignment:', [...selectedKeys]);

93

}

94

});

95

let { groupProps } = useToggleButtonGroup({

96

'aria-label': 'Text alignment',

97

orientation: 'horizontal'

98

}, state, groupRef);

99

100

return (

101

<div {...groupProps} ref={groupRef} style={{ display: 'flex', gap: 2 }}>

102

<ToggleButtonGroupItem id="left" state={state}>

103

Left

104

</ToggleButtonGroupItem>

105

<ToggleButtonGroupItem id="center" state={state}>

106

Center

107

</ToggleButtonGroupItem>

108

<ToggleButtonGroupItem id="right" state={state}>

109

Right

110

</ToggleButtonGroupItem>

111

</div>

112

);

113

}

114

115

// Multiple selection group

116

function FeatureToggles() {

117

let groupRef = useRef<HTMLDivElement | null>(null);

118

let state = useToggleGroupState({

119

selectedKeys: ['bold'],

120

selectionMode: 'multiple',

121

onChange: (selectedKeys) => {

122

console.log('Active features:', [...selectedKeys]);

123

}

124

});

125

let { groupProps } = useToggleButtonGroup({

126

'aria-label': 'Text formatting options'

127

}, state, groupRef);

128

129

return (

130

<div {...groupProps} ref={groupRef} style={{ display: 'flex', gap: 4 }}>

131

<ToggleButtonGroupItem id="bold" state={state}>

132

<strong>B</strong>

133

</ToggleButtonGroupItem>

134

<ToggleButtonGroupItem id="italic" state={state}>

135

<em>I</em>

136

</ToggleButtonGroupItem>

137

<ToggleButtonGroupItem id="underline" state={state}>

138

<u>U</u>

139

</ToggleButtonGroupItem>

140

</div>

141

);

142

}

143

```

144

145

### Toggle Button Group Props Interface

146

147

Configuration options for toggle button groups.

148

149

```typescript { .api }

150

interface AriaToggleButtonGroupProps extends ToggleGroupProps, AriaLabelingProps {

151

/**

152

* The orientation of the toggle button group.

153

* @default 'horizontal'

154

*/

155

orientation?: Orientation;

156

/** Whether the toggle button group is disabled. */

157

isDisabled?: boolean;

158

}

159

160

interface ToggleGroupProps {

161

/** The currently selected keys in the collection (controlled). */

162

selectedKeys?: 'all' | Iterable<Key>;

163

/** The initial selected keys in the collection (uncontrolled). */

164

defaultSelectedKeys?: 'all' | Iterable<Key>;

165

/** Handler that is called when the selection changes. */

166

onChange?: (keys: Selection) => void;

167

/** The type of selection that is allowed in the collection. */

168

selectionMode?: SelectionMode;

169

/** Whether the collection allows empty selection. */

170

disallowEmptySelection?: boolean;

171

}

172

173

type SelectionMode = 'none' | 'single' | 'multiple';

174

type Selection = 'all' | Set<Key>;

175

type Orientation = 'horizontal' | 'vertical';

176

```

177

178

### Toggle Button Group Return Interface

179

180

Return value from the useToggleButtonGroup hook.

181

182

```typescript { .api }

183

interface ToggleButtonGroupAria {

184

/**

185

* Props for the toggle button group container.

186

*/

187

groupProps: DOMAttributes;

188

}

189

```

190

191

### Toggle Button Group Item Props Interface

192

193

Configuration options for individual toggle button group items.

194

195

```typescript { .api }

196

interface AriaToggleButtonGroupItemOptions<E extends ElementType> extends Omit<AriaToggleButtonGroupItemProps<E>, 'children'> {

197

/** An identifier for the item in the selectedKeys of a ToggleButtonGroup. */

198

id: Key;

199

/** The HTML element or React element used to render the button. @default 'button' */

200

elementType?: E | JSXElementConstructor<any>;

201

/** Whether the button is disabled. */

202

isDisabled?: boolean;

203

/** Handler that is called when the press is released over the target. */

204

onPress?: (e: PressEvent) => void;

205

/** Handler that is called when a press interaction starts. */

206

onPressStart?: (e: PressEvent) => void;

207

/** Handler that is called when a press interaction ends. */

208

onPressEnd?: (e: PressEvent) => void;

209

/** Handler that is called when the press state changes. */

210

onPressChange?: (isPressed: boolean) => void;

211

/** Handler that is called when a press is released over the target. */

212

onPressUp?: (e: PressEvent) => void;

213

/** Whether to prevent focus from moving to the button when pressing it. */

214

preventFocusOnPress?: boolean;

215

}

216

```

217

218

### Toggle Group State Interface

219

220

State management interface for toggle button groups (from @react-stately/toggle).

221

222

```typescript { .api }

223

interface ToggleGroupState {

224

/** The keys for the currently selected items. */

225

selectedKeys: Set<Key>;

226

/** Whether the collection allows empty selection. */

227

disallowEmptySelection: boolean;

228

/** The selection mode for the collection. */

229

selectionMode: SelectionMode;

230

/** Whether the collection is disabled. */

231

isDisabled: boolean;

232

/** Sets the selected keys. */

233

setSelected(key: Key, selected: boolean): void;

234

/** Toggles the selection state of an item. */

235

toggleKey(key: Key): void;

236

/** Replaces the selection with only the given key. */

237

selectKey(key: Key): void;

238

/** Selects all items in the collection. */

239

selectAll(): void;

240

/** Clears the selection. */

241

clearSelection(): void;

242

}

243

```

244

245

## State Management

246

247

Toggle button groups require state management via the `useToggleGroupState` hook from `@react-stately/toggle`:

248

249

```typescript

250

import { useToggleGroupState } from "@react-stately/toggle";

251

252

// Single selection mode (radio group behavior)

253

let state = useToggleGroupState({

254

selectionMode: 'single',

255

selectedKeys: ['option1'],

256

onChange: (keys) => console.log('Selected:', [...keys])

257

});

258

259

// Multiple selection mode (checkbox group behavior)

260

let state = useToggleGroupState({

261

selectionMode: 'multiple',

262

selectedKeys: ['option1', 'option3'],

263

onChange: (keys) => console.log('Selected:', [...keys])

264

});

265

266

// No selection allowed

267

let state = useToggleGroupState({

268

selectionMode: 'none'

269

});

270

```

271

272

## Selection Modes

273

274

### Single Selection Mode

275

- Behaves like a radio group

276

- Only one item can be selected at a time

277

- Selecting a new item deselects the previous one

278

- ARIA role="radiogroup" on container

279

- ARIA role="radio" on items

280

- Uses `aria-checked` instead of `aria-pressed`

281

282

### Multiple Selection Mode

283

- Behaves like a checkbox group

284

- Multiple items can be selected simultaneously

285

- Items can be toggled independently

286

- ARIA role="toolbar" on container

287

- ARIA role="button" on items

288

- Uses `aria-pressed` for selection state

289

290

### No Selection Mode

291

- Items cannot be selected

292

- Used for command buttons that trigger actions

293

- ARIA role="toolbar" on container

294

- No selection state management

295

296

## Accessibility Features

297

298

- **ARIA Roles**: Automatic role assignment based on selection mode

299

- **Keyboard Navigation**: Arrow key navigation between items

300

- **Selection States**: Proper ARIA attributes for selection

301

- **Screen Reader Support**: Clear group and item identification

302

- **Focus Management**: Roving tabindex for keyboard navigation

303

- **Disabled States**: Group and item level disabled support

304

305

## Orientation Support

306

307

Groups support both horizontal and vertical orientations:

308

309

- **Horizontal**: Left/Right arrow key navigation

310

- **Vertical**: Up/Down arrow key navigation

311

- **Automatic ARIA**: Proper `aria-orientation` attribute

312

313

## Integration with Toolbar

314

315

`useToggleButtonGroup` internally uses `useToolbar` from `@react-aria/toolbar` for:

316

317

- Keyboard navigation

318

- Focus management

319

- ARIA toolbar semantics

320

- Orientation handling

321

322

## Item Coordination

323

324

Group items automatically coordinate with the group state:

325

326

- **Selection Sync**: Item selection reflects group state

327

- **State Updates**: Item interactions update group state

328

- **Disabled Inheritance**: Items inherit group disabled state

329

- **Focus Management**: Shared focus management across items