🎨 style: update button and button icon only theme

This commit is contained in:
Wahyu Kurniawan 2024-02-19 21:15:29 +07:00
parent 6a3af491ca
commit 862862a9c5
No known key found for this signature in database
GPG Key ID: 040A1549143A8E33
2 changed files with 98 additions and 55 deletions

View File

@ -7,20 +7,20 @@ import type { VariantProps } from 'tailwind-variants';
export const buttonTheme = tv(
{
base: [
'h-fit',
'inline-flex',
'items-center',
'justify-center',
'font-medium',
'whitespace-nowrap',
'focus-ring',
'disabled:cursor-not-allowed',
],
variants: {
size: {
lg: ['gap-3', 'py-4', 'px-6', 'rounded-lg', 'text-lg'],
md: ['gap-2', 'py-3', 'px-4', 'rounded-lg', 'text-base'],
sm: ['gap-1', 'py-2', 'px-2', 'rounded-md', 'text-xs'],
xs: ['gap-1', 'py-1', 'px-2', 'rounded-md', 'text-xs'],
lg: ['gap-2', 'py-3.5', 'px-5', 'text-base', 'tracking-[-0.011em]'],
md: ['gap-2', 'py-3.25', 'px-5', 'text-sm', 'tracking-[-0.006em]'],
sm: ['gap-1', 'py-2', 'px-3', 'text-xs'],
xs: ['gap-1', 'py-1', 'px-2', 'text-xs'],
},
fullWidth: {
true: 'w-full',
@ -29,11 +29,14 @@ export const buttonTheme = tv(
default: '',
rounded: 'rounded-full',
},
iconOnly: {
true: '',
},
variant: {
primary: [
'text-elements-on-primary',
'border',
'border-primary-700',
'border-transparent',
'bg-controls-primary',
'shadow-button',
'hover:bg-controls-primary-hovered',
@ -44,86 +47,108 @@ export const buttonTheme = tv(
'disabled:shadow-none',
],
secondary: [
'text-components-buttons-secondary-foreground',
'text-elements-on-secondary',
'border',
'border-primary-500',
'bg-components-buttons-secondary-background',
'hover:text-components-buttons-secondary-foreground-hover',
'hover:bg-components-buttons-secondary-background-hover',
'focus-visible:text-components-buttons-secondary-foreground-focus',
'focus-visible:bg-components-buttons-secondary-background-focus',
'disabled:text-components-buttons-secondary-foreground-disabled',
'disabled:bg-components-buttons-secondary-background-disabled ',
'border-transparent',
'bg-controls-secondary',
'hover:bg-controls-secondary-hovered',
'focus-visible:bg-controls-secondary-hovered',
'disabled:text-elements-on-disabled',
'disabled:bg-controls-disabled',
'disabled:border-transparent',
'disabled:shadow-none',
],
tertiary: [
'text-components-buttons-tertiary-background',
'text-elements-on-tertiary',
'border',
'border-components-buttons-tertiary-background',
'border-border-interactive/10',
'bg-transparent',
'hover:text-components-buttons-tertiary-hover',
'hover:border-components-buttons-tertiary-hover',
'focus-visible:text-components-buttons-tertiary-focus',
'focus-visible:border-components-buttons-tertiary-focus',
'disabled:text-components-buttons-tertiary-disabled',
'disabled:border-components-buttons-tertiary-disabled',
'hover:bg-controls-tertiary-hovered',
'hover:border-border-interactive-hovered',
'hover:border-border-interactive-hovered/[0.14]',
'focus-visible:bg-controls-tertiary-hovered',
'focus-visible:border-border-interactive-hovered',
'focus-visible:border-border-interactive-hovered/[0.14]',
'disabled:text-elements-on-disabled',
'disabled:bg-controls-disabled',
'disabled:border-transparent',
'disabled:shadow-none',
],
'text-only': [
'text-components-buttons-text-only-background',
ghost: [
'text-elements-on-tertiary',
'border',
'border-transparent',
'bg-transparent',
'hover:text-components-buttons-text-only-foreground-hover',
'hover:bg-components-buttons-text-only-background-hover',
'focus-visible:text-components-buttons-text-only-foreground-focus',
'focus-visible:bg-components-buttons-text-only-background-focus',
'disabled:text-components-buttons-tertiary-disabled',
'disabled:bg-transparent',
'hover:bg-controls-tertiary-hovered',
'hover:border-border-interactive-hovered',
'hover:border-border-interactive-hovered/[0.14]',
'focus-visible:bg-controls-tertiary-hovered',
'focus-visible:border-border-interactive-hovered',
'focus-visible:border-border-interactive-hovered/[0.14]',
'disabled:text-elements-on-disabled',
'disabled:bg-controls-disabled',
'disabled:border-transparent',
'disabled:shadow-none',
],
danger: [
'text-components-button-icon-alert-foreground',
'text-elements-on-danger',
'border',
'border-transparent',
'bg-components-buttons-alert-background',
'hover:text-components-buttons-alert-foreground-hover',
'hover:bg-components-buttons-alert-background-hover',
'focus-visible:text-components-buttons-alert-foreground-focus',
'focus-visible:bg-components-buttons-alert-background-focus',
'disabled:text-components-button-icon-alert-foreground-disabled',
'disabled:bg-components-button-icon-alert-background-disabled',
'bg-border-danger',
'hover:bg-controls-danger-hovered',
'focus-visible:bg-controls-danger-hovered',
'disabled:text-elements-on-disabled',
'disabled:bg-controls-disabled',
'disabled:border-transparent',
'disabled:shadow-none',
],
'icon-only': [
'p-0 flex items-center justify-center',
'text-components-button-icon-text-only-foreground',
'danger-ghost': [
'text-elements-danger',
'border',
'border-transparent',
'bg-transparent',
'hover:text-components-button-icon-text-only-foreground-hover',
'hover:bg-components-button-icon-text-only-background-hover',
'focus-visible:text-components-button-icon-low-emphasis-foreground-focus',
'focus-visible:bg-components-button-icon-low-emphasis-background-focus',
'disabled:text-components-button-icon-low-emphasis-outlined-foreground-disabled',
'disabled:bg-transparent',
'hover:bg-controls-tertiary-hovered',
'hover:border-border-interactive-hovered',
'hover:border-border-interactive-hovered/[0.14]',
'focus-visible:bg-controls-tertiary-hovered',
'focus-visible:border-border-interactive-hovered',
'focus-visible:border-border-interactive-hovered/[0.14]',
'disabled:text-elements-on-disabled',
'disabled:bg-controls-disabled',
'disabled:border-transparent',
'disabled:shadow-none',
],
unstyled: [],
},
},
compoundVariants: [
{
size: 'lg',
iconOnly: true,
class: ['py-3.5', 'px-3.5'],
},
{
size: 'md',
variant: 'icon-only',
class: ['h-11', 'w-11', 'rounded-lg'],
iconOnly: true,
class: ['py-3.25', 'px-3.25'],
},
{
size: 'sm',
variant: 'icon-only',
class: ['h-8', 'w-8', 'rounded-md'],
iconOnly: true,
class: ['py-2', 'px-2'],
},
{
size: 'xs',
iconOnly: true,
class: ['py-1', 'px-1'],
},
],
defaultVariants: {
size: 'md',
variant: 'primary',
fullWidth: false,
iconOnly: false,
shape: 'rounded',
},
},
{

View File

@ -4,6 +4,7 @@ import type { ComponentPropsWithoutRef, ReactNode } from 'react';
import { buttonTheme } from './Button.theme';
import type { ButtonTheme } from './Button.theme';
import { Link } from 'react-router-dom';
import { cloneIcon } from 'utils/cloneIcon';
/**
* Represents the properties of a base button component.
@ -69,6 +70,7 @@ const Button = ({
leftIcon,
rightIcon,
fullWidth,
iconOnly,
shape,
variant,
...props
@ -114,15 +116,17 @@ const Button = ({
variant = 'primary',
size = 'md',
fullWidth = false,
iconOnly = false,
shape = 'rounded',
as,
}) => ({
variant,
size,
fullWidth,
iconOnly,
shape,
as,
}))({ ...props, fullWidth, shape, variant });
}))({ ...props, fullWidth, iconOnly, shape, variant });
/**
* Validates that a button component has either children or an aria-label prop.
@ -133,14 +137,28 @@ const Button = ({
);
}
const iconSize = useCallback(() => {
switch (styleProps.size) {
case 'lg':
return { width: 20, height: 20 };
case 'sm':
case 'xs':
return { width: 16, height: 16 };
case 'md':
default: {
return { width: 18, height: 18 };
}
}
}, [styleProps.size])();
return (
<Component
{...props}
className={buttonTheme({ ...styleProps, class: className })}
>
{leftIcon}
{cloneIcon(leftIcon, { ...iconSize })}
{children}
{rightIcon}
{cloneIcon(rightIcon, { ...iconSize })}
</Component>
);
};