Skip to content

Commit

Permalink
Start implementation of button loading state
Browse files Browse the repository at this point in the history
  • Loading branch information
cgero-eth committed Sep 19, 2023
1 parent 20c7638 commit e544966
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 6 deletions.
33 changes: 28 additions & 5 deletions src/components/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import classNames from 'classnames';
import type { ButtonHTMLAttributes } from 'react';
import { Icon, type IconType } from '../icon';
import type { IconSize } from '../icon/icon';
import { Spinner } from '../spinner';
import type { SpinnerSize, SpinnerVariant } from '../spinner/spinner';

export type ButtonVariant = 'primary' | 'secondary' | 'tertiary' | 'success' | 'warning' | 'critical';
export type ButtonSize = 'lg' | 'md' | 'sm';
Expand Down Expand Up @@ -68,10 +70,19 @@ const variantToClassNames: Record<ButtonVariant, string[]> = {
],
};

const variantToSpinnerVariant: Record<ButtonVariant, SpinnerVariant> = {
primary: 'primary',
secondary: 'neutral',
tertiary: 'neutral',
success: 'success',
warning: 'warning',
critical: 'critical',
};

const sizeToClassNames: Record<ButtonSize, string> = {
lg: 'h-[48px] rounded-xl px-4 gap-1',
md: 'h-[40px] rounded-xl px-3 gap-1',
sm: 'h-[32px] rounded-lg px-2 gap-0.5',
lg: 'h-[48px] rounded-xl px-4 gap-2',
md: 'h-[40px] rounded-xl px-3 gap-2',
sm: 'h-[32px] rounded-lg px-2 gap-1.5',
};

const sizeToIconSize: Record<ButtonSize, IconSize> = {
Expand All @@ -80,16 +91,28 @@ const sizeToIconSize: Record<ButtonSize, IconSize> = {
sm: 'sm',
};

const sizeToSpinnerSize: Record<ButtonSize, SpinnerSize> = {
lg: 'md',
md: 'md',
sm: 'sm',
};

export const Button: React.FC<IButtonProps> = (props) => {
const { variant, size, iconRight, iconLeft, className, children, state, ...otherProps } = props;

const commonClasses = 'flex flex-row border items-center focus:outline enabled:hover:shadow-md';
const commonClasses = 'flex flex-row border items-center focus:outline';
const variantClasses = variantToClassNames[variant].join(' ');
const classes = classNames(commonClasses, variantClasses, sizeToClassNames[size], className);
const classes = classNames(commonClasses, variantClasses, sizeToClassNames[size], className, {
'hover:shadow-md': state !== 'disabled' && state != 'loading',
'cursor-progress': state === 'loading',
});

return (
<button className={classes} disabled={state === 'disabled'} {...otherProps}>
{iconLeft && <Icon icon={iconLeft} size={sizeToIconSize[size]} />}
{state === 'loading' && (
<Spinner size={sizeToSpinnerSize[size]} variant={variantToSpinnerVariant[variant]} />
)}
{children}
{iconRight && <Icon icon={iconRight} size={sizeToIconSize[size]} />}
</button>
Expand Down
2 changes: 1 addition & 1 deletion src/components/spinner/spinner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const sizeToDimension: Record<SpinnerSize, number> = {

const variantToClassNames: Record<SpinnerVariant, string> = {
neutral: 'border-neutral-100 border-t-primary-400',
primary: 'border-neutral-0 border-t-primary-300',
primary: 'border-primary-300 border-t-neutral-0',
success: 'border-success-300 border-t-success-800',
warning: 'border-warning-300 border-t-warning-800',
critical: 'border-critical-300 border-t-critical-800',
Expand Down

0 comments on commit e544966

Please sign in to comment.