0
# Toggle Button Functionality
1
2
Extends button behavior with selection state management for toggle buttons that maintain on/off states. The `useToggleButton` hook builds on `useButton` to provide accessible toggle functionality with proper ARIA pressed states.
3
4
## Capabilities
5
6
### useToggleButton Hook
7
8
Creates accessible toggle button behavior with selection state management.
9
10
```typescript { .api }
11
/**
12
* Provides the behavior and accessibility implementation for a toggle button component.
13
* ToggleButtons allow users to toggle a selection on or off, for example switching between two states or modes.
14
*/
15
function useToggleButton(props: AriaToggleButtonOptions<'button'>, state: ToggleState, ref: RefObject<HTMLButtonElement | null>): ToggleButtonAria<ButtonHTMLAttributes<HTMLButtonElement>>;
16
function useToggleButton(props: AriaToggleButtonOptions<'a'>, state: ToggleState, ref: RefObject<HTMLAnchorElement | null>): ToggleButtonAria<AnchorHTMLAttributes<HTMLAnchorElement>>;
17
function useToggleButton(props: AriaToggleButtonOptions<'div'>, state: ToggleState, ref: RefObject<HTMLDivElement | null>): ToggleButtonAria<HTMLAttributes<HTMLDivElement>>;
18
function useToggleButton(props: AriaToggleButtonOptions<'input'>, state: ToggleState, ref: RefObject<HTMLInputElement | null>): ToggleButtonAria<InputHTMLAttributes<HTMLInputElement>>;
19
function useToggleButton(props: AriaToggleButtonOptions<'span'>, state: ToggleState, ref: RefObject<HTMLSpanElement | null>): ToggleButtonAria<HTMLAttributes<HTMLSpanElement>>;
20
function useToggleButton(props: AriaToggleButtonOptions<ElementType>, state: ToggleState, ref: RefObject<Element | null>): ToggleButtonAria<DOMAttributes>;
21
```
22
23
**Usage Examples:**
24
25
```typescript
26
import { useToggleButton } from "@react-aria/button";
27
import { useToggleState } from "@react-stately/toggle";
28
import { useRef, useState } from "react";
29
30
// Basic toggle button
31
function ToggleButton(props) {
32
let ref = useRef<HTMLButtonElement | null>(null);
33
let state = useToggleState(props);
34
let { buttonProps, isPressed, isSelected, isDisabled } = useToggleButton(props, state, ref);
35
36
return (
37
<button
38
{...buttonProps}
39
style={{
40
background: isPressed
41
? (isSelected ? 'darkgreen' : 'gray')
42
: (isSelected ? 'green' : 'lightgray'),
43
color: isSelected ? 'white' : 'black',
44
padding: 10,
45
border: 'none'
46
}}
47
ref={ref}>
48
{props.children}
49
</button>
50
);
51
}
52
53
// Controlled toggle button
54
function ControlledToggleButton() {
55
let [isSelected, setSelected] = useState(false);
56
57
return (
58
<ToggleButton
59
isSelected={isSelected}
60
onChange={setSelected}
61
aria-label="Toggle favorite">
62
★
63
</ToggleButton>
64
);
65
}
66
67
// Custom element toggle button
68
function CustomToggleButton(props) {
69
let ref = useRef<HTMLDivElement | null>(null);
70
let state = useToggleState(props);
71
let { buttonProps, isSelected, isPressed } = useToggleButton({
72
...props,
73
elementType: 'div'
74
}, state, ref);
75
76
return (
77
<div
78
{...buttonProps}
79
style={{
80
background: isSelected ? '#007acc' : '#f0f0f0',
81
color: isSelected ? 'white' : 'black',
82
padding: '8px 16px',
83
border: isPressed ? '2px solid #005a9e' : '2px solid transparent',
84
borderRadius: 4,
85
cursor: 'pointer',
86
userSelect: 'none'
87
}}
88
ref={ref}>
89
{props.children}
90
</div>
91
);
92
}
93
```
94
95
### Toggle Button Options Interface
96
97
Configuration options for toggle button behavior.
98
99
```typescript { .api }
100
interface AriaToggleButtonOptions<E extends ElementType> extends Omit<AriaToggleButtonProps<E>, 'children'> {
101
/** The HTML element or React element used to render the button. @default 'button' */
102
elementType?: E | JSXElementConstructor<any>;
103
/** Whether the button is disabled. */
104
isDisabled?: boolean;
105
/** Whether the element should be selected (controlled). */
106
isSelected?: boolean;
107
/** Whether the element should be selected (uncontrolled). */
108
defaultSelected?: boolean;
109
/** Handler that is called when the element's selection state changes. */
110
onChange?: (isSelected: boolean) => void;
111
/** Handler that is called when the press is released over the target. */
112
onPress?: (e: PressEvent) => void;
113
/** Handler that is called when a press interaction starts. */
114
onPressStart?: (e: PressEvent) => void;
115
/** Handler that is called when a press interaction ends. */
116
onPressEnd?: (e: PressEvent) => void;
117
/** Handler that is called when the press state changes. */
118
onPressChange?: (isPressed: boolean) => void;
119
/** Handler that is called when a press is released over the target. */
120
onPressUp?: (e: PressEvent) => void;
121
/** Whether to prevent focus from moving to the button when pressing it. */
122
preventFocusOnPress?: boolean;
123
/** Standard onClick handler (called in addition to onPress). */
124
onClick?: (e: MouseEvent) => void;
125
}
126
```
127
128
### Toggle Button Return Interface
129
130
Return value from the useToggleButton hook containing props and state.
131
132
```typescript { .api }
133
interface ToggleButtonAria<T> extends ButtonAria<T> {
134
/** Whether the button is selected. */
135
isSelected: boolean;
136
/** Whether the button is disabled. */
137
isDisabled: boolean;
138
}
139
```
140
141
### Toggle State Interface
142
143
State management interface for toggle buttons (from @react-stately/toggle).
144
145
```typescript { .api }
146
interface ToggleState {
147
/** Whether the toggle is selected. */
148
isSelected: boolean;
149
/** Sets whether the toggle is selected. */
150
setSelected(isSelected: boolean): void;
151
/** Toggles the selection state. */
152
toggle(): void;
153
}
154
```
155
156
## State Management
157
158
Toggle buttons require state management via the `useToggleState` hook from `@react-stately/toggle`:
159
160
```typescript
161
import { useToggleState } from "@react-stately/toggle";
162
163
// Uncontrolled (default selection)
164
let state = useToggleState({ defaultSelected: false });
165
166
// Controlled
167
let state = useToggleState({
168
isSelected: isSelected,
169
onChange: setSelected
170
});
171
```
172
173
## Element Type Support
174
175
Like `useButton`, `useToggleButton` supports multiple HTML element types:
176
177
### Native Button Element (`elementType: 'button'`)
178
- Standard button behavior with toggle state
179
- `aria-pressed` attribute for screen readers
180
- No form-related props (removed from toggle button interface)
181
182
### Anchor Element (`elementType: 'a'`)
183
- ARIA role="button" with aria-pressed
184
- No href support (not applicable for toggle buttons)
185
- Disabled state via aria-disabled
186
187
### Generic Elements (`elementType: 'div' | 'span'`)
188
- ARIA role="button" with aria-pressed
189
- Full keyboard support
190
- Visual press and selection states
191
192
### Input Element (`elementType: 'input'`)
193
- ARIA role="button" with aria-pressed
194
- Native disabled attribute support
195
- Input type support limited
196
197
## Accessibility Features
198
199
- **ARIA Pressed State**: Automatic `aria-pressed` attribute management
200
- **Screen Reader Support**: Clear selection state announcement
201
- **Keyboard Support**: Space and Enter key toggle functionality
202
- **Focus Management**: Proper focus behavior across element types
203
- **State Changes**: Accessible state change notifications
204
- **Visual Indicators**: Press and selection state support for styling
205
206
## Selection State Handling
207
208
The toggle button automatically manages:
209
210
- **Press Events**: Integrates with button press handling
211
- **State Synchronization**: Keeps UI in sync with state
212
- **Change Events**: Fires onChange when selection state changes
213
- **ARIA Attributes**: Updates aria-pressed based on selection
214
- **Default State**: Supports both controlled and uncontrolled patterns
215
216
## Integration with useButton
217
218
`useToggleButton` internally uses `useButton` and extends it with:
219
220
- Selection state management
221
- Toggle functionality on press
222
- ARIA pressed state attributes
223
- State synchronization
224
- onChange event integration
225
226
All `useButton` functionality (press states, element types, accessibility) is preserved and enhanced with toggle capabilities.