62 lines
2 KiB
TypeScript
62 lines
2 KiB
TypeScript
|
|
import Link from "next/link";
|
||
|
|
import React, { FC, ReactElement, ReactNode } from "react";
|
||
|
|
import classNames from "classnames";
|
||
|
|
|
||
|
|
interface ButtonProps {
|
||
|
|
appearance?: 'solid' | 'outline' | 'text';
|
||
|
|
children: ReactNode;
|
||
|
|
className?: string;
|
||
|
|
href?: string;
|
||
|
|
icon?: ReactNode;
|
||
|
|
onClick?: () => void;
|
||
|
|
disabled?: boolean;
|
||
|
|
size?: 'small' | 'medium' | 'large';
|
||
|
|
type?: 'button' | 'submit' | 'reset';
|
||
|
|
variant?: 'primary' | 'secondary' | 'accent';
|
||
|
|
}
|
||
|
|
|
||
|
|
const Button: FC<ButtonProps> = ({ appearance, children, className, disabled, href, icon, onClick,
|
||
|
|
size = 'medium', type,
|
||
|
|
variant = 'primary'
|
||
|
|
}) => {
|
||
|
|
const styles = classNames(
|
||
|
|
"flex items-center space-x-1",
|
||
|
|
"justify-center font-size-18 py-2 px-4 rounded flex",
|
||
|
|
{
|
||
|
|
'border-2 border-primary background-red text-white': variant === 'primary' && appearance === 'solid',
|
||
|
|
'border-2 border-primary text-primary': variant === 'primary' && appearance === 'outline',
|
||
|
|
'text-primary': variant === 'primary' && appearance === 'text',
|
||
|
|
'border-2 border-secondary text-secondary': variant === 'secondary' && appearance === 'outline',
|
||
|
|
'border-2 border-accent-blue text-accent-blue': variant === 'accent' && appearance === 'outline',
|
||
|
|
},
|
||
|
|
className
|
||
|
|
)
|
||
|
|
|
||
|
|
const iconClassNames = classNames({
|
||
|
|
"h-4 w-4 mr-1": size === "small",
|
||
|
|
"h-5 w-5 mr-1": size === "medium",
|
||
|
|
"h-7 w-7 mr-2": size === "large",
|
||
|
|
});
|
||
|
|
|
||
|
|
const iconElement =
|
||
|
|
React.isValidElement(icon) &&
|
||
|
|
React.cloneElement(icon as ReactElement<{ className?: string }>, {
|
||
|
|
className: iconClassNames,
|
||
|
|
});
|
||
|
|
|
||
|
|
if (href !== undefined) {
|
||
|
|
return (
|
||
|
|
<Link href={href} className={styles}>
|
||
|
|
{ icon && iconElement}
|
||
|
|
{ children}
|
||
|
|
</Link>
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
return <button onClick={onClick} className={styles} disabled={disabled} type={ type ?? 'button'}>
|
||
|
|
{ icon && iconElement}
|
||
|
|
{ children }
|
||
|
|
</button>
|
||
|
|
}
|
||
|
|
|
||
|
|
export default Button
|