Files
dndbeyond_src/ddb_main/components/Toggle/Toggle.tsx
T

60 lines
1.3 KiB
TypeScript

import clsx from "clsx";
import { useState, type FC, type HTMLAttributes } from "react";
import styles from "./styles.module.css";
export interface ToggleProps
extends Omit<HTMLAttributes<HTMLButtonElement>, "onClick"> {
checked?: boolean;
color?: "primary" | "secondary" | "warning" | "error" | "info" | "success" | "themed";
onClick?: (isEnabled: boolean) => void;
onChangePromise?: (
newIsEnabled: boolean,
accept: () => void,
reject: () => void
) => void;
disabled?: boolean;
}
export const Toggle: FC<ToggleProps> = ({
checked,
className,
color = "primary",
onClick,
onChangePromise,
...props
}) => {
const [enabled, setEnabled] = useState(checked);
const handleClick = (evt: React.MouseEvent): void => {
evt.stopPropagation();
evt.nativeEvent.stopImmediatePropagation();
if (onChangePromise) {
onChangePromise(
!enabled,
() => {
setEnabled(!enabled);
},
() => {}
);
} else if (onClick) {
onClick(!enabled);
setEnabled(!enabled);
}
};
return (
<button
className={clsx([
styles.toggle,
styles[color],
checked && styles.checked,
className,
])}
onClick={handleClick}
aria-pressed={checked}
{...props}
/>
);
};