83 lines
2.3 KiB
TypeScript
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>
|
|
);
|
|
},
|
|
);
|