import type {
AnchorHTMLAttributes,
ButtonHTMLAttributes,
ReactNode,
} from 'react';
import { forwardRef } from 'react';
import type { IconName } from '../icon';
import { Icon } from '../icon';
import classnames from 'classnames';
type ButtonVariant = 'default' | 'primary' | 'secondary';
type ButtonSize = 'lg' | 'md' | 'sm';
const base =
'inline-block uppercase border rounded-md disabled:opacity-40 transition-colors';
const sm = 'px-2 py-1 text-sm';
const md = 'px-10 py-2 text-base';
const lg = 'px-14 py-4';
const fillClasses = 'block w-full';
const defaultClasses = [
'text-black dark:text-white',
'border-black dark:border-white',
'bg-white dark:bg-black',
'enabled:hover:bg-neutral-200 dark:enabled:hover:bg-neutral-800',
'enabled:active:bg-neutral-200 dark:enabled:active:bg-neutral-500',
];
const primary = [
'text-black',
'border-vega-yellow',
'bg-vega-yellow',
'enabled:hover:bg-vega-yellow-dark enabled:hover:border-vega-yellow-dark',
'enabled:active:bg-vega-yellow-dark enabled:active:border-vega-yellow-dark',
];
const secondary = [
'text-white',
'border-vega-pink',
'bg-vega-pink',
'enabled:hover:bg-vega-pink-dark enabled:hover:border-vega-pink-dark',
'enabled:active:bg-vega-pink-dark enabled:active:border-vega-pink-dark',
];
const getClassname = ({
variant,
size,
fill,
className,
}: {
variant: ButtonVariant;
size: ButtonSize;
fill: boolean;
className?: string;
}) => {
return classnames(base, className, {
[defaultClasses.join(' ')]: variant === 'default',
[primary.join(' ')]: variant === 'primary',
[secondary.join(' ')]: variant === 'secondary',
[lg]: size === 'lg',
[md]: size === 'md',
[sm]: size === 'sm',
[fillClasses]: fill,
});
};
interface CommonProps {
children?: ReactNode;
variant?: ButtonVariant;
disabled?: boolean;
fill?: boolean;
size?: ButtonSize;
icon?: IconName;
rightIcon?: IconName;
}
export interface ButtonProps
extends ButtonHTMLAttributes,
CommonProps {}
export const Button = forwardRef(
(
{
variant = 'default',
size = 'md',
fill = false,
type = 'button',
icon,
rightIcon,
children,
className,
...props
},
ref
) => {
const buttonClasses = getClassname({ variant, size, fill, className });
return (
);
}
);
export interface AnchorButtonProps
extends AnchorHTMLAttributes,
CommonProps {}
export const AnchorButton = forwardRef(
(
{
variant = 'default',
size = 'lg',
fill = false,
icon,
rightIcon,
children,
...props
},
ref
) => {
const className = getClassname({ variant, size, fill });
return (
{children}
);
}
);
type ButtonLinkProps = Omit<
ButtonHTMLAttributes,
'className' | 'style'
>;
export const ButtonLink = forwardRef(
({ type = 'button', ...props }, ref) => {
const className = classnames('inline underline');
return ;
}
);
interface ButtonContentProps {
children: ReactNode;
icon?: IconName;
rightIcon?: IconName;
}
const ButtonContent = ({ children, icon, rightIcon }: ButtonContentProps) => {
const iconEl = icon ? (
) : null;
const rightIconEl = rightIcon ? (
) : null;
return (
<>
{iconEl}
{children}
{rightIconEl}
>
);
};