Just use isSelected directly rather than makking the button have its own state. Also, the isPressed from useToggleButton looks like its whether the user has the mouse button down on it or not rather than whether the toggle switch is on, which was making the state wrong.
38 lines
966 B
JavaScript
38 lines
966 B
JavaScript
import React, { useCallback, useRef } from "react";
|
|
import styles from "./Toggle.module.css";
|
|
import { useToggleButton } from "@react-aria/button";
|
|
import classNames from "classnames";
|
|
import { Field } from "./Input";
|
|
|
|
export function Toggle({ id, label, className, onChange, isSelected }) {
|
|
const buttonRef = useRef();
|
|
const toggle = useCallback(() => {
|
|
onChange(!isSelected);
|
|
});
|
|
const { buttonProps } = useToggleButton({ isSelected }, { toggle }, buttonRef);
|
|
|
|
return (
|
|
<Field
|
|
className={classNames(
|
|
styles.toggle,
|
|
{ [styles.on]: isSelected },
|
|
className
|
|
)}
|
|
>
|
|
<button
|
|
{...buttonProps}
|
|
ref={buttonRef}
|
|
id={id}
|
|
className={classNames(styles.button, {
|
|
[styles.isPressed]: isSelected,
|
|
})}
|
|
>
|
|
<div className={styles.ball} />
|
|
</button>
|
|
<label className={styles.label} htmlFor={id}>
|
|
{label}
|
|
</label>
|
|
</Field>
|
|
);
|
|
}
|