material-you-react/src/primitive-components/icon-button/icon-button.tsx

83 lines
2.3 KiB
TypeScript

'use client';
import { Icon } from '../components';
import { ButtonLayout } from '../button-layout/button-layout';
import { IconButtonProps, StateToggleIconType } from './icon-button.types';
import {
forwardRef,
MouseEventHandler,
useCallback,
useImperativeHandle,
useRef,
useState,
} from 'react';
/**
* Icon button-layout component
** description
*/
export const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(
(
{
icon,
variant,
disabled,
selected = false,
toggled = false,
centralRipple,
...props
},
ref,
) => {
const [toggleIcon, setToggleIcon] = useState<StateToggleIconType>({
state: selected == true ? 'selected' : 'unselected',
icon: toggled ? toggled.unselected ?? 'add_circle' : 'add_circle',
});
const toggle = (classes: string, icon: string) => {
setToggleIcon({
state: classes,
icon: icon,
});
};
const buttonRef = useRef<HTMLButtonElement>(null);
const callback = event => {
if (toggled) {
if (toggleIcon.state === 'selected') {
toggle('', toggled.unselected ?? 'add_circle');
} else {
toggle('selected', toggled.selected ?? 'add_circle');
}
}
if (props.onClick) {
props.onClick.apply(null, event);
}
};
useImperativeHandle(ref, () => buttonRef.current);
return (
<ButtonLayout
{...props}
centralRipple={centralRipple}
className={`m3-icon-button ${toggleIcon.state} ${toggled ? 'toggled' : ''}`.trimEnd()}
disabled={disabled}
onClick={callback}
ref={buttonRef}
variant={variant ? variant : 'default'}
>
<Icon
fillIcon={toggleIcon.state === 'selected' ? 1 : 0}
iconSize={28}
svgSize={40}
>
{toggled ? toggleIcon.icon : icon ? icon : undefined}
</Icon>
</ButtonLayout>
);
},
);