bigbuffet-rw/app/soapbox/components/ui/button/button.tsx

86 lines
1.6 KiB
TypeScript
Raw Normal View History

2022-03-21 11:09:01 -07:00
import * as React from 'react';
import { Link } from 'react-router-dom';
import Icon from 'soapbox/components/icon';
import { useButtonStyles } from './useButtonStyles';
import type { ButtonSizes, ButtonThemes } from './useButtonStyles';
interface IButton {
block?: boolean,
children?: React.ReactNode,
classNames?: string,
disabled?: boolean,
icon?: string,
onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void,
size?: ButtonSizes,
style?: React.CSSProperties,
text?: React.ReactNode,
to?: string,
theme?: ButtonThemes,
type?: 'button' | 'submit',
}
const Button = React.forwardRef<HTMLButtonElement, IButton>((props, ref): JSX.Element => {
const {
block = false,
children,
disabled = false,
icon,
onClick,
size = 'md',
text,
theme = 'accent',
to,
type = 'button',
} = props;
const themeClass = useButtonStyles({
theme,
block,
disabled,
size,
});
const renderIcon = () => {
if (!icon) {
return null;
}
return <Icon src={icon} className='mr-2' />;
};
const handleClick = React.useCallback((event) => {
if (onClick && !disabled) {
onClick(event);
}
}, [onClick, disabled]);
const renderButton = () => (
<button
className={themeClass}
disabled={disabled}
onClick={handleClick}
ref={ref}
type={type}
data-testid='button'
2022-03-21 11:09:01 -07:00
>
{renderIcon()}
{text || children}
</button>
);
if (to) {
return (
<Link to={to} tabIndex={-1} className='inline-flex'>
{renderButton()}
</Link>
);
}
return renderButton();
});
export default Button;