import { Children, isValidElement, cloneElement, ChangeEvent, forwardRef, memo, ReactElement, Ref, useCallback, useState, useId } from "react"; import { TextSpan } from "../Text"; import { SpacingSpan } from "../Spacing"; import CheckboxIcon from "./Elements/CheckboxIcon"; import HiddenCheckbox from "./Elements/HiddenCheckbox"; import { ICheckboxProps } from "./types"; const Checkbox = forwardRef(function Checkbox( props: ICheckboxProps, ref: Ref ) { const { isChecked: isCheckedProp, isDisabled = false, isSwitch = false, defaultChecked = false, onChange: onChangeProps, title, name, value, children, textProps, className, ..._rest } = props; const [isCheckedState, setIsCheckedState] = useState( isCheckedProp !== undefined ? isCheckedProp : defaultChecked ); const onChange = useCallback( (e: ChangeEvent) => { setIsCheckedState(e.target.checked); if (onChangeProps) { onChangeProps(e); } }, [onChangeProps] ); // Use isChecked from the state if it is controlled const isChecked = isCheckedProp === undefined ? isCheckedState : isCheckedProp; const id = useId(); // Add props to children const childrenWithProps = Children.map(children, (child) => { // Checking isValidElement is the safe way and avoids a typescript // error too. if (isValidElement(child)) { return cloneElement( child as ReactElement<{ isDisabled: boolean; isChecked: boolean; style: any; }>, { isDisabled, isChecked, style: { fontSize: "inherit" } } ); } return child; }); return ( {childrenWithProps} ); }); Checkbox.displayName = "Checkbox"; export default memo(Checkbox);