87 lines
2.4 KiB
TypeScript
87 lines
2.4 KiB
TypeScript
|
'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>
|
||
|
);
|
||
|
},
|
||
|
);
|