Skip to content

Commit 6d5eb42

Browse files
committed
refactor: use generic types in Toggle to match ToggleGroup
1 parent a2a7d92 commit 6d5eb42

File tree

2 files changed

+17
-13
lines changed

2 files changed

+17
-13
lines changed

packages/react/src/toggle/Toggle.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ describe('<Toggle />', () => {
117117
}
118118

119119
await render(
120-
<ToggleGroup defaultValue={['left']}>
120+
<ToggleGroup defaultValue="left">
121121
<Toggle value="left" render={(props) => <ToggleRenderComponent renderProps={props} />} />
122122
</ToggleGroup>,
123123
);

packages/react/src/toggle/Toggle.tsx

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@ import {
1818
*
1919
* Documentation: [Base UI Toggle](https://base-ui.com/react/components/toggle)
2020
*/
21-
export const Toggle = React.forwardRef(function Toggle(
22-
componentProps: Toggle.Props,
23-
forwardedRef: React.ForwardedRef<HTMLButtonElement>,
24-
) {
21+
export function Toggle<Value>(componentProps: Toggle.Props<Value>) {
2522
const {
2623
className,
2724
defaultPressed: defaultPressedProp = false,
@@ -33,21 +30,24 @@ export const Toggle = React.forwardRef(function Toggle(
3330
type, // cannot change button type
3431
value: valueProp,
3532
nativeButton = true,
33+
toggleRef = { current: null },
3634
...elementProps
3735
} = componentProps;
3836

3937
const value = valueProp ?? '';
4038

4139
const groupContext = useToggleGroupContext();
4240

43-
const groupValue = groupContext?.value ?? [];
41+
const groupValue = groupContext?.value;
42+
43+
const selected = Array.isArray(groupValue) ? groupValue.includes(value) : groupValue === value;
4444

4545
const defaultPressed = groupContext ? undefined : defaultPressedProp;
4646

4747
const disabled = (disabledProp || groupContext?.disabled) ?? false;
4848

4949
const [pressed, setPressedState] = useControlled({
50-
controlled: groupContext && value ? groupValue?.indexOf(value) > -1 : pressedProp,
50+
controlled: groupContext && value ? selected : pressedProp,
5151
default: defaultPressed,
5252
name: 'Toggle',
5353
state: 'pressed',
@@ -73,7 +73,7 @@ export const Toggle = React.forwardRef(function Toggle(
7373
[disabled, pressed],
7474
);
7575

76-
const refs = [buttonRef, forwardedRef];
76+
const refs = [buttonRef, toggleRef];
7777
const props = [
7878
{
7979
'aria-pressed': pressed,
@@ -115,7 +115,7 @@ export const Toggle = React.forwardRef(function Toggle(
115115
}
116116

117117
return element;
118-
});
118+
}
119119

120120
export interface ToggleState {
121121
/**
@@ -128,9 +128,9 @@ export interface ToggleState {
128128
disabled: boolean;
129129
}
130130

131-
export interface ToggleProps
131+
export interface ToggleProps<Value>
132132
extends NativeButtonProps,
133-
BaseUIComponentProps<'button', Toggle.State> {
133+
Omit<BaseUIComponentProps<'button', Toggle.State>, 'value'> {
134134
/**
135135
* Whether the toggle button is currently pressed.
136136
* This is the controlled counterpart of `defaultPressed`.
@@ -155,7 +155,11 @@ export interface ToggleProps
155155
* A unique string that identifies the toggle when used
156156
* inside a toggle group.
157157
*/
158-
value?: string;
158+
value?: Value;
159+
/**
160+
* The ref of the element.
161+
**/
162+
toggleRef?: React.RefObject<HTMLButtonElement>;
159163
}
160164

161165
export type ToggleChangeEventReason = 'none';
@@ -164,7 +168,7 @@ export type ToggleChangeEventDetails = BaseUIChangeEventDetails<Toggle.ChangeEve
164168

165169
export namespace Toggle {
166170
export type State = ToggleState;
167-
export type Props = ToggleProps;
171+
export type Props<Value> = ToggleProps<Value>;
168172
export type ChangeEventReason = ToggleChangeEventReason;
169173
export type ChangeEventDetails = ToggleChangeEventDetails;
170174
}

0 commit comments

Comments
 (0)