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

86 lines
2.5 KiB
TypeScript
Raw Normal View History

2024-02-01 00:58:19 +03:00
'use client';
import { Icon } from '../../components';
2024-02-02 13:39:02 +03:00
import { bool, oneOf, string } from 'prop-types';
2024-02-01 00:58:19 +03:00
import { ButtonLayout } from '../button-layout/button-layout';
import { forwardRef, useImperativeHandle, useRef, useState } from 'react';
2024-02-02 13:39:02 +03:00
import { IconButtonProps, StateToggleIconType } from './icon-button.types';
2024-02-01 00:58:19 +03:00
/**
* Icon button-layout component
** description
*/
2024-02-01 15:23:59 +03:00
export const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(
2024-02-01 00:58:19 +03:00
(
{
icon,
2024-02-02 13:39:02 +03:00
className = '',
2024-02-01 00:58:19 +03:00
toggled = false,
2024-02-02 13:39:02 +03:00
disabled = false,
selected = false,
variant = 'default',
centralRipple = false,
2024-02-01 00:58:19 +03:00
...props
},
ref,
) => {
2024-02-01 15:23:59 +03:00
const [toggleIcon, setToggleIcon] = useState<StateToggleIconType>({
2024-02-01 00:58:19 +03:00
state: selected == true ? 'selected' : 'unselected',
icon: toggled ? toggled.unselected ?? 'add_circle' : 'add_circle',
});
2024-02-02 13:39:02 +03:00
const classes = `m3-icon-button ${toggleIcon.state} ${variant} ${toggled ? 'toggled' : ''} ${className}`;
2024-02-01 00:58:19 +03:00
const toggle = (classes: string, icon: string) => {
2024-02-01 15:23:59 +03:00
setToggleIcon({
2024-02-01 00:58:19 +03:00
state: classes,
icon: icon,
2024-02-01 15:23:59 +03:00
});
2024-02-01 00:58:19 +03:00
};
const buttonRef = useRef<HTMLButtonElement>(null);
2024-02-01 22:37:22 +03:00
const callback = event => {
if (toggled) {
if (toggleIcon.state === 'selected') {
toggle('', toggled.unselected ?? 'add_circle');
} else {
toggle('selected', toggled.selected ?? 'add_circle');
2024-02-01 00:58:19 +03:00
}
2024-02-01 22:37:22 +03:00
}
if (props.onClick) {
props.onClick.apply(null, event);
}
};
2024-02-01 00:58:19 +03:00
useImperativeHandle(ref, () => buttonRef.current);
return (
<ButtonLayout
{...props}
centralRipple={centralRipple}
2024-02-02 13:39:02 +03:00
className={classes}
2024-02-01 00:58:19 +03:00
disabled={disabled}
onClick={callback}
ref={buttonRef}
>
<Icon
2024-02-01 21:24:37 +03:00
fillIcon={toggleIcon.state === 'selected' ? 1 : 0}
2024-02-01 00:58:19 +03:00
iconSize={28}
svgSize={40}
>
{toggled ? toggleIcon.icon : icon ? icon : undefined}
</Icon>
</ButtonLayout>
);
},
);
2024-02-02 13:39:02 +03:00
IconButton.propTypes = {
icon: string,
selected: bool,
centralRipple: bool,
variant: oneOf(['default', 'filled', 'tonal', 'outlined']),
};