60 lines
1.7 KiB
TypeScript
60 lines
1.7 KiB
TypeScript
|
'use client';
|
||
|
|
||
|
import { RippleArea } from '../ripple/ripple-area';
|
||
|
import { IRippleProps } from '../ripple/ripple.types';
|
||
|
import useRippleEffect from '../ripple/hooks/useRippleEffect';
|
||
|
import { CheckBoxLayout } from '../checkbox-layout/check-box-layout';
|
||
|
import {
|
||
|
forwardRef,
|
||
|
PropsWithChildren,
|
||
|
useEffect,
|
||
|
useImperativeHandle,
|
||
|
useRef,
|
||
|
useState,
|
||
|
} from 'react';
|
||
|
|
||
|
/**
|
||
|
* Checkbox component
|
||
|
** description
|
||
|
*/
|
||
|
|
||
|
export const Checkbox = forwardRef<
|
||
|
HTMLInputElement,
|
||
|
PropsWithChildren<any> & IRippleProps
|
||
|
>(({ centralRipple, ...props }, ref) => {
|
||
|
const [isActive, setIsActive] = useState<boolean>(false),
|
||
|
[checked, setChecked] = useState<boolean>(props.checked ?? false),
|
||
|
ripplesRef = useRef(null),
|
||
|
checkboxRef = useRef(null),
|
||
|
events = useRippleEffect(ripplesRef, setIsActive);
|
||
|
|
||
|
const classes =
|
||
|
`m3 m3-checkbox-label ${isActive === true ? 'visible' : ''}`.trimEnd();
|
||
|
const indeterminate = (props.indeterminate === true).toString();
|
||
|
|
||
|
useImperativeHandle(ref, () => checkboxRef.current);
|
||
|
|
||
|
useEffect(() => {
|
||
|
setChecked(!checked);
|
||
|
}, [checkboxRef.current?.checked]);
|
||
|
|
||
|
return (
|
||
|
<label {...events} className={classes}>
|
||
|
<CheckBoxLayout
|
||
|
{...props}
|
||
|
indeterminate={indeterminate}
|
||
|
ref={checkboxRef}
|
||
|
type={'checkbox'}
|
||
|
/>
|
||
|
<span className={'m3 m3-checkbox-state-layer'} />
|
||
|
<RippleArea
|
||
|
callback={setIsActive}
|
||
|
central={centralRipple}
|
||
|
className={'m3-checkbox-ripple-layer'}
|
||
|
ref={ripplesRef}
|
||
|
/>
|
||
|
{props.children}
|
||
|
</label>
|
||
|
);
|
||
|
});
|