forked from cerc-io/snowballtools-base
🎨 style: update button and button icon only theme
This commit is contained in:
parent
6a3af491ca
commit
862862a9c5
@ -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',
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user