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(
|
export const buttonTheme = tv(
|
||||||
{
|
{
|
||||||
base: [
|
base: [
|
||||||
|
'h-fit',
|
||||||
'inline-flex',
|
'inline-flex',
|
||||||
'items-center',
|
'items-center',
|
||||||
'justify-center',
|
'justify-center',
|
||||||
'font-medium',
|
|
||||||
'whitespace-nowrap',
|
'whitespace-nowrap',
|
||||||
'focus-ring',
|
'focus-ring',
|
||||||
'disabled:cursor-not-allowed',
|
'disabled:cursor-not-allowed',
|
||||||
],
|
],
|
||||||
variants: {
|
variants: {
|
||||||
size: {
|
size: {
|
||||||
lg: ['gap-3', 'py-4', 'px-6', 'rounded-lg', 'text-lg'],
|
lg: ['gap-2', 'py-3.5', 'px-5', 'text-base', 'tracking-[-0.011em]'],
|
||||||
md: ['gap-2', 'py-3', 'px-4', 'rounded-lg', 'text-base'],
|
md: ['gap-2', 'py-3.25', 'px-5', 'text-sm', 'tracking-[-0.006em]'],
|
||||||
sm: ['gap-1', 'py-2', 'px-2', 'rounded-md', 'text-xs'],
|
sm: ['gap-1', 'py-2', 'px-3', 'text-xs'],
|
||||||
xs: ['gap-1', 'py-1', 'px-2', 'rounded-md', 'text-xs'],
|
xs: ['gap-1', 'py-1', 'px-2', 'text-xs'],
|
||||||
},
|
},
|
||||||
fullWidth: {
|
fullWidth: {
|
||||||
true: 'w-full',
|
true: 'w-full',
|
||||||
@ -29,11 +29,14 @@ export const buttonTheme = tv(
|
|||||||
default: '',
|
default: '',
|
||||||
rounded: 'rounded-full',
|
rounded: 'rounded-full',
|
||||||
},
|
},
|
||||||
|
iconOnly: {
|
||||||
|
true: '',
|
||||||
|
},
|
||||||
variant: {
|
variant: {
|
||||||
primary: [
|
primary: [
|
||||||
'text-elements-on-primary',
|
'text-elements-on-primary',
|
||||||
'border',
|
'border',
|
||||||
'border-primary-700',
|
'border-transparent',
|
||||||
'bg-controls-primary',
|
'bg-controls-primary',
|
||||||
'shadow-button',
|
'shadow-button',
|
||||||
'hover:bg-controls-primary-hovered',
|
'hover:bg-controls-primary-hovered',
|
||||||
@ -44,86 +47,108 @@ export const buttonTheme = tv(
|
|||||||
'disabled:shadow-none',
|
'disabled:shadow-none',
|
||||||
],
|
],
|
||||||
secondary: [
|
secondary: [
|
||||||
'text-components-buttons-secondary-foreground',
|
'text-elements-on-secondary',
|
||||||
'border',
|
'border',
|
||||||
'border-primary-500',
|
'border-transparent',
|
||||||
'bg-components-buttons-secondary-background',
|
'bg-controls-secondary',
|
||||||
'hover:text-components-buttons-secondary-foreground-hover',
|
'hover:bg-controls-secondary-hovered',
|
||||||
'hover:bg-components-buttons-secondary-background-hover',
|
'focus-visible:bg-controls-secondary-hovered',
|
||||||
'focus-visible:text-components-buttons-secondary-foreground-focus',
|
'disabled:text-elements-on-disabled',
|
||||||
'focus-visible:bg-components-buttons-secondary-background-focus',
|
'disabled:bg-controls-disabled',
|
||||||
'disabled:text-components-buttons-secondary-foreground-disabled',
|
|
||||||
'disabled:bg-components-buttons-secondary-background-disabled ',
|
|
||||||
'disabled:border-transparent',
|
'disabled:border-transparent',
|
||||||
|
'disabled:shadow-none',
|
||||||
],
|
],
|
||||||
tertiary: [
|
tertiary: [
|
||||||
'text-components-buttons-tertiary-background',
|
'text-elements-on-tertiary',
|
||||||
'border',
|
'border',
|
||||||
'border-components-buttons-tertiary-background',
|
'border-border-interactive/10',
|
||||||
'bg-transparent',
|
'bg-transparent',
|
||||||
'hover:text-components-buttons-tertiary-hover',
|
'hover:bg-controls-tertiary-hovered',
|
||||||
'hover:border-components-buttons-tertiary-hover',
|
'hover:border-border-interactive-hovered',
|
||||||
'focus-visible:text-components-buttons-tertiary-focus',
|
'hover:border-border-interactive-hovered/[0.14]',
|
||||||
'focus-visible:border-components-buttons-tertiary-focus',
|
'focus-visible:bg-controls-tertiary-hovered',
|
||||||
'disabled:text-components-buttons-tertiary-disabled',
|
'focus-visible:border-border-interactive-hovered',
|
||||||
'disabled:border-components-buttons-tertiary-disabled',
|
'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': [
|
ghost: [
|
||||||
'text-components-buttons-text-only-background',
|
'text-elements-on-tertiary',
|
||||||
'border',
|
'border',
|
||||||
'border-transparent',
|
'border-transparent',
|
||||||
'bg-transparent',
|
'bg-transparent',
|
||||||
'hover:text-components-buttons-text-only-foreground-hover',
|
'hover:bg-controls-tertiary-hovered',
|
||||||
'hover:bg-components-buttons-text-only-background-hover',
|
'hover:border-border-interactive-hovered',
|
||||||
'focus-visible:text-components-buttons-text-only-foreground-focus',
|
'hover:border-border-interactive-hovered/[0.14]',
|
||||||
'focus-visible:bg-components-buttons-text-only-background-focus',
|
'focus-visible:bg-controls-tertiary-hovered',
|
||||||
'disabled:text-components-buttons-tertiary-disabled',
|
'focus-visible:border-border-interactive-hovered',
|
||||||
'disabled:bg-transparent',
|
'focus-visible:border-border-interactive-hovered/[0.14]',
|
||||||
|
'disabled:text-elements-on-disabled',
|
||||||
|
'disabled:bg-controls-disabled',
|
||||||
|
'disabled:border-transparent',
|
||||||
|
'disabled:shadow-none',
|
||||||
],
|
],
|
||||||
danger: [
|
danger: [
|
||||||
'text-components-button-icon-alert-foreground',
|
'text-elements-on-danger',
|
||||||
'border',
|
'border',
|
||||||
'border-transparent',
|
'border-transparent',
|
||||||
'bg-components-buttons-alert-background',
|
'bg-border-danger',
|
||||||
'hover:text-components-buttons-alert-foreground-hover',
|
'hover:bg-controls-danger-hovered',
|
||||||
'hover:bg-components-buttons-alert-background-hover',
|
'focus-visible:bg-controls-danger-hovered',
|
||||||
'focus-visible:text-components-buttons-alert-foreground-focus',
|
'disabled:text-elements-on-disabled',
|
||||||
'focus-visible:bg-components-buttons-alert-background-focus',
|
'disabled:bg-controls-disabled',
|
||||||
'disabled:text-components-button-icon-alert-foreground-disabled',
|
'disabled:border-transparent',
|
||||||
'disabled:bg-components-button-icon-alert-background-disabled',
|
'disabled:shadow-none',
|
||||||
],
|
],
|
||||||
'icon-only': [
|
'danger-ghost': [
|
||||||
'p-0 flex items-center justify-center',
|
'text-elements-danger',
|
||||||
'text-components-button-icon-text-only-foreground',
|
|
||||||
'border',
|
'border',
|
||||||
'border-transparent',
|
'border-transparent',
|
||||||
'bg-transparent',
|
'bg-transparent',
|
||||||
'hover:text-components-button-icon-text-only-foreground-hover',
|
'hover:bg-controls-tertiary-hovered',
|
||||||
'hover:bg-components-button-icon-text-only-background-hover',
|
'hover:border-border-interactive-hovered',
|
||||||
'focus-visible:text-components-button-icon-low-emphasis-foreground-focus',
|
'hover:border-border-interactive-hovered/[0.14]',
|
||||||
'focus-visible:bg-components-button-icon-low-emphasis-background-focus',
|
'focus-visible:bg-controls-tertiary-hovered',
|
||||||
'disabled:text-components-button-icon-low-emphasis-outlined-foreground-disabled',
|
'focus-visible:border-border-interactive-hovered',
|
||||||
'disabled:bg-transparent',
|
'focus-visible:border-border-interactive-hovered/[0.14]',
|
||||||
|
'disabled:text-elements-on-disabled',
|
||||||
|
'disabled:bg-controls-disabled',
|
||||||
|
'disabled:border-transparent',
|
||||||
|
'disabled:shadow-none',
|
||||||
],
|
],
|
||||||
unstyled: [],
|
unstyled: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
compoundVariants: [
|
compoundVariants: [
|
||||||
|
{
|
||||||
|
size: 'lg',
|
||||||
|
iconOnly: true,
|
||||||
|
class: ['py-3.5', 'px-3.5'],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
size: 'md',
|
size: 'md',
|
||||||
variant: 'icon-only',
|
iconOnly: true,
|
||||||
class: ['h-11', 'w-11', 'rounded-lg'],
|
class: ['py-3.25', 'px-3.25'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
size: 'sm',
|
size: 'sm',
|
||||||
variant: 'icon-only',
|
iconOnly: true,
|
||||||
class: ['h-8', 'w-8', 'rounded-md'],
|
class: ['py-2', 'px-2'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 'xs',
|
||||||
|
iconOnly: true,
|
||||||
|
class: ['py-1', 'px-1'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
defaultVariants: {
|
defaultVariants: {
|
||||||
size: 'md',
|
size: 'md',
|
||||||
variant: 'primary',
|
variant: 'primary',
|
||||||
fullWidth: false,
|
fullWidth: false,
|
||||||
|
iconOnly: false,
|
||||||
|
shape: 'rounded',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,7 @@ import type { ComponentPropsWithoutRef, ReactNode } from 'react';
|
|||||||
import { buttonTheme } from './Button.theme';
|
import { buttonTheme } from './Button.theme';
|
||||||
import type { ButtonTheme } from './Button.theme';
|
import type { ButtonTheme } from './Button.theme';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
import { cloneIcon } from 'utils/cloneIcon';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the properties of a base button component.
|
* Represents the properties of a base button component.
|
||||||
@ -69,6 +70,7 @@ const Button = ({
|
|||||||
leftIcon,
|
leftIcon,
|
||||||
rightIcon,
|
rightIcon,
|
||||||
fullWidth,
|
fullWidth,
|
||||||
|
iconOnly,
|
||||||
shape,
|
shape,
|
||||||
variant,
|
variant,
|
||||||
...props
|
...props
|
||||||
@ -114,15 +116,17 @@ const Button = ({
|
|||||||
variant = 'primary',
|
variant = 'primary',
|
||||||
size = 'md',
|
size = 'md',
|
||||||
fullWidth = false,
|
fullWidth = false,
|
||||||
|
iconOnly = false,
|
||||||
shape = 'rounded',
|
shape = 'rounded',
|
||||||
as,
|
as,
|
||||||
}) => ({
|
}) => ({
|
||||||
variant,
|
variant,
|
||||||
size,
|
size,
|
||||||
fullWidth,
|
fullWidth,
|
||||||
|
iconOnly,
|
||||||
shape,
|
shape,
|
||||||
as,
|
as,
|
||||||
}))({ ...props, fullWidth, shape, variant });
|
}))({ ...props, fullWidth, iconOnly, shape, variant });
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates that a button component has either children or an aria-label prop.
|
* 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 (
|
return (
|
||||||
<Component
|
<Component
|
||||||
{...props}
|
{...props}
|
||||||
className={buttonTheme({ ...styleProps, class: className })}
|
className={buttonTheme({ ...styleProps, class: className })}
|
||||||
>
|
>
|
||||||
{leftIcon}
|
{cloneIcon(leftIcon, { ...iconSize })}
|
||||||
{children}
|
{children}
|
||||||
{rightIcon}
|
{cloneIcon(rightIcon, { ...iconSize })}
|
||||||
</Component>
|
</Component>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user