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

87 lines
2.4 KiB
TypeScript
Raw Normal View History

2024-02-01 00:58:19 +03:00
'use client';
import { Icon } from '../material-you-components';
import { toggleIconType } from './icon-button.types';
import { IRippleProps } from '../ripple/ripple.types';
import { ButtonLayout } from '../button-layout/button-layout';
import { IconButtonMainProps } from '../button-layout/button.types';
import {
forwardRef,
useCallback,
useImperativeHandle,
useRef,
useState,
} from 'react';
/**
* Icon button-layout component
** description
*/
export const IconButton = forwardRef<
HTMLButtonElement,
IconButtonMainProps & IRippleProps
>(
(
{
icon,
variant,
disabled,
selected = false,
toggled = false,
centralRipple,
...props
},
ref,
) => {
const [toggleIcon, setToggleIcon] = useState<toggleIconType>({
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 = useCallback(() => {
if (toggled) {
if (toggleIcon.state === 'selected') {
toggle('', toggled.unselected ?? 'add_circle');
} else {
toggle('selected', toggled.selected ?? 'add_circle');
}
}
if (props.onClick) {
props.onClick();
}
}, [toggleIcon]);
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
fill={toggleIcon.state === 'selected' ? 1 : 0}
iconSize={28}
svgSize={40}
>
{toggled ? toggleIcon.icon : icon ? icon : undefined}
</Icon>
</ButtonLayout>
);
},
);