vega-frontend-monorepo/libs/ui-toolkit/src/components/button/Button.tsx

120 lines
4.0 KiB
TypeScript
Raw Normal View History

2022-03-01 09:26:26 +00:00
import classNames from 'classnames';
2022-03-02 09:56:05 +00:00
import { Icon, IconName } from '../icon';
2022-03-01 09:26:26 +00:00
export interface ButtonProps {
tag?: 'a' | 'button';
children?: React.ReactNode;
onClick?: React.MouseEventHandler<HTMLButtonElement> &
React.MouseEventHandler<HTMLAnchorElement>;
variant?: 'primary' | 'secondary' | 'accent' | 'inline';
disabled?: boolean;
className?: string;
2022-03-02 09:56:05 +00:00
prependIconName?: IconName;
appendIconName?: IconName;
2022-03-01 09:26:26 +00:00
}
export function Button({
tag = 'button',
variant = 'primary',
children,
onClick,
disabled,
className,
2022-03-02 09:56:05 +00:00
prependIconName,
appendIconName,
2022-03-01 09:26:26 +00:00
}: ButtonProps) {
const ButtonTag: keyof JSX.IntrinsicElements = tag;
const effectiveClassName = classNames(
[
'inline-flex',
'items-center',
2022-03-03 11:11:36 +00:00
'justify-center',
2022-03-04 16:21:24 +00:00
// 'bg-clip-padding',
2022-03-01 09:26:26 +00:00
'box-border',
'h-28',
'border',
'text-ui',
'no-underline',
'hover:underline',
'disabled:no-underline',
2022-03-03 14:48:40 +00:00
'transition-all',
2022-03-01 09:26:26 +00:00
],
{
2022-03-03 11:11:36 +00:00
'pl-28': !(
className?.match(/(^| )p(l|x)-\d+( |$)/) || variant === 'inline'
),
'pr-28': !(
className?.match(/(^| )p(r|x)-\d+( |$)/) || variant === 'inline'
),
2022-03-03 14:48:40 +00:00
'hover:border-black dark:hover:border-white': variant !== 'inline',
'active:border-black dark:active:border-white': true,
2022-03-01 09:26:26 +00:00
2022-03-03 14:48:40 +00:00
'bg-black dark:bg-white': variant === 'primary',
'border-black/60 dark:border-white/60':
variant === 'primary' || variant === 'secondary',
'text-white dark:text-black': variant === 'primary',
'hover:bg-black/70 dark:hover:bg-white/70': variant === 'primary',
'active:bg-white dark:active:bg-black':
variant === 'primary' || variant === 'accent',
'active:text-black dark:active:text-white':
variant === 'primary' || variant === 'accent',
'bg-white dark:bg-black': variant === 'secondary',
'text-black dark:text-white': variant === 'secondary',
'hover:bg-black/25 dark:hover:bg-white/25': variant === 'secondary',
'hover:text-black dark:hover:text-white':
2022-03-01 09:26:26 +00:00
variant === 'secondary' || variant === 'accent',
2022-03-03 14:48:40 +00:00
'active:bg-black dark:active:bg-white': variant === 'secondary',
'active:text-white dark:active:text-black': variant === 'secondary',
2022-03-01 09:26:26 +00:00
uppercase: variant === 'accent',
2022-03-03 14:48:40 +00:00
'bg-vega-yellow dark:bg-vega-yellow': variant === 'accent',
'border-transparent dark:border-transparent':
variant === 'accent' || variant === 'inline',
2022-03-04 16:21:24 +00:00
'hover:bg-vega-yellow-dark dark:hover:bg-vega-yellow/30':
2022-03-03 14:48:40 +00:00
variant === 'accent',
2022-03-04 16:21:24 +00:00
'hover:text-white dark:hover:text-white': variant === 'accent',
2022-03-01 09:26:26 +00:00
'pl-4': variant === 'inline',
'pr-4': variant === 'inline',
'border-0': variant === 'inline',
underline: variant === 'inline',
'hover:no-underline': variant === 'inline',
2022-03-04 16:21:24 +00:00
'hover:border-transparent dark:hover:border-transparent':
2022-03-03 14:48:40 +00:00
variant === 'inline',
2022-03-04 16:21:24 +00:00
'active:border-transparent dark:active:border-transparent':
variant === 'inline',
'active:text-black dark:active:text-vega-yellow': variant === 'inline',
2022-03-03 14:48:40 +00:00
'text-black/95 dark:text-white/95': variant === 'inline',
'hover:text-black hover:dark:text-white': variant === 'inline',
'disabled:bg-black/10 dark:disabled:bg-white/10': variant !== 'inline',
'disabled:text-black/60 dark:disabled:text-white/60':
variant !== 'inline',
'disabled:border-black/25 dark:disabled:border-white/25':
variant !== 'inline',
2022-03-01 09:26:26 +00:00
},
className
);
2022-03-02 09:56:05 +00:00
let icon;
const iconName = prependIconName || appendIconName;
if (iconName !== undefined) {
const iconClassName = classNames(['fill-current'], {
'mr-8': prependIconName,
'ml-8': appendIconName,
});
icon = <Icon name={iconName} className={iconClassName} size={16} />;
}
2022-03-01 09:26:26 +00:00
return (
<ButtonTag
onClick={onClick}
className={effectiveClassName}
disabled={disabled}
>
2022-03-02 09:56:05 +00:00
{prependIconName && icon}
2022-03-01 09:26:26 +00:00
{children}
2022-03-02 09:56:05 +00:00
{appendIconName && icon}
2022-03-01 09:26:26 +00:00
</ButtonTag>
);
}