feat: buttons with icons in tailwind
i am not proud of some of this code
This commit is contained in:
@@ -1,22 +1,20 @@
|
||||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
import styles from './Button.module.scss';
|
||||
import { ThemeColor, getThemeColorHexByName, getThemeColorRgbByName } from '../../../../shared/util/themeColors';
|
||||
import type IconComponent from '~icons/material-symbols';
|
||||
import Text from '../Text/Text';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
variant?: 'filled' | 'outline' | 'single';
|
||||
variant: 'filled' | 'outline' | 'single';
|
||||
onClick?: () => void;
|
||||
icon?: React.ReactNode;
|
||||
icon?: typeof IconComponent;
|
||||
disabled?: boolean;
|
||||
title?: string;
|
||||
testId?: string;
|
||||
useScss?: boolean;
|
||||
color: ThemeColor;
|
||||
}
|
||||
|
||||
const BUTTON_BASE_CLASS =
|
||||
'm-2.5 h-10 w-auto flex cursor-pointer content-center items-center gap-2 rounded-1 px-4 py-0 text-4.5 font-500 leading-normal font-sans btn-transition';
|
||||
|
||||
/**
|
||||
* A reusable button component that follows the design system of the extension.
|
||||
* @returns
|
||||
@@ -29,34 +27,49 @@ export function Button({
|
||||
icon,
|
||||
disabled,
|
||||
title,
|
||||
testId,
|
||||
color,
|
||||
children,
|
||||
useScss = false,
|
||||
}: React.PropsWithChildren<Props>): JSX.Element {
|
||||
const Icon = icon;
|
||||
const isIconOnly = !children && !!icon;
|
||||
const colorHex = getThemeColorHexByName(color);
|
||||
const colorRgb = getThemeColorRgbByName(color).join(' ');
|
||||
|
||||
return (
|
||||
<button
|
||||
style={
|
||||
{
|
||||
...style,
|
||||
'--color-primary': '#333F48',
|
||||
'--color-secondary': '#FFFFFF',
|
||||
'--color': colorHex,
|
||||
'--bg-color-8': `rgba(${colorRgb} / 0.08)`,
|
||||
'--shadow-color-15': `rgba(${colorRgb} / 0.15)`,
|
||||
'--shadow-color-30': `rgba(${colorRgb} / 0.3)`,
|
||||
} as React.CSSProperties
|
||||
}
|
||||
data-testid={testId}
|
||||
className={clsx(useScss ? styles.button : BUTTON_BASE_CLASS, className, {
|
||||
[styles[variant]]: useScss,
|
||||
[styles.disabled]: disabled && useScss,
|
||||
'disabled:(cursor-not-allowed opacity-50)': disabled && !useScss,
|
||||
'color-white border-none': variant === 'filled' && !useScss,
|
||||
'border-current border-solid border-1 bg-white': variant === 'outline' && !useScss,
|
||||
'bg-white border-none': variant === 'single' && !useScss,
|
||||
})}
|
||||
className={clsx(
|
||||
'btn',
|
||||
{
|
||||
'disabled:(cursor-not-allowed opacity-50)': disabled,
|
||||
'color-white bg-[var(--color)] border-[var(--color)] hover:btn-shadow': variant === 'filled',
|
||||
'color-[var(--color)] bg-white border-current hover:btn-shade border border-solid':
|
||||
variant === 'outline',
|
||||
'color-[var(--color)] bg-white border-white hover:btn-shade': variant === 'single', // settings is the only "single"
|
||||
'px-2 py-1.25': isIconOnly && variant !== 'outline',
|
||||
'px-1.75 py-1.25': isIconOnly && variant === 'outline',
|
||||
'px-3.75': variant === 'outline' && !isIconOnly,
|
||||
},
|
||||
className
|
||||
)}
|
||||
title={title}
|
||||
disabled={disabled}
|
||||
onClick={disabled ? undefined : onClick}
|
||||
>
|
||||
{icon}
|
||||
{children}
|
||||
{icon && <Icon className='size-6' />}
|
||||
{!isIconOnly && (
|
||||
<Text variant='h4' className='translate-y-0.08'>
|
||||
{children}
|
||||
</Text>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user