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

83 lines
1.8 KiB
TypeScript

import clsx from "clsx";
import { ChangeEvent, FC, useEffect, useState } from "react";
import {
Checkbox as TtuiCheckbox,
CheckboxProps as TtuiCheckboxProps,
} from "@dndbeyond/ttui/components/Checkbox";
import styles from "./styles.module.css";
interface CheckboxProps extends TtuiCheckboxProps {
themed?: boolean;
darkMode?: boolean;
variant?: "default" | "builder" | "sidebar";
onChangeConfirm?: (
newIsEnabled: boolean,
accept: () => void,
reject: () => void
) => void;
}
export const Checkbox: FC<CheckboxProps> = ({
className,
themed,
variant = "default",
darkMode,
checked = false,
onChangeConfirm,
onChange,
disabled,
...props
}) => {
const [isChecked, setIsChecked] = useState(checked);
const handleChange = (evt: ChangeEvent<HTMLInputElement>): void => {
evt.stopPropagation();
evt.nativeEvent.stopImmediatePropagation();
const newCheckedState = evt.target.checked;
// promise-based logic
if (onChangeConfirm) {
onChangeConfirm(
newCheckedState,
() => {
// Promise accepted, update the state
setIsChecked(newCheckedState);
},
() => {
// Promise rejected, reset the checkbox to its previous state
setIsChecked(!newCheckedState);
}
);
} else {
// Update the state immediately if no promise handling - only IF onClick is provided
if (onChange) {
onChange(evt);
setIsChecked(newCheckedState);
}
}
};
useEffect(() => {
setIsChecked(checked);
}, [checked]);
return (
<TtuiCheckbox
className={clsx([
styles.checkbox,
styles[variant],
themed && styles.themed,
className,
])}
onChange={handleChange}
aria-pressed={isChecked}
checked={isChecked}
disabled={disabled}
{...props}
/>
);
};