export type ButtonVariant = | 'text' | 'flat' | 'raised' | 'outline' | 'link' | null; export type ButtonColor = | null | 'primary' | 'danger' | 'positive' | 'paper' | 'chip' | 'white'; interface SharedButtonStyleProps { variant?: ButtonVariant; color?: ButtonColor; border?: string; shadow?: string; whitespace?: string; display?: string; } export function getSharedButtonStyle( props: SharedButtonStyleProps, ): (string | boolean | null | undefined)[] { const { variant, shadow, whitespace = 'whitespace-nowrap', display = 'inline-flex', } = props; const variantProps = {...props, border: props.border || 'border'}; let style: string[] = []; if (variant === 'outline') { style = outline(variantProps); } else if (variant === 'text') { style = text(variantProps); } else if (variant === 'flat' || variant === 'raised') { style = contained(variantProps); } else if (variant === 'link') { style = link(variantProps); } return [ ...style, shadow || (variant === 'raised' && 'shadow-md'), whitespace, display, variant && 'align-middle flex-shrink-0 items-center transition-button duration-200', 'select-none appearance-none no-underline outline-none disabled:pointer-events-none disabled:cursor-default', ]; } function outline({color, border}: SharedButtonStyleProps) { const disabled = 'disabled:text-disabled disabled:bg-transparent disabled:border-disabled-bg'; switch (color) { case 'primary': return [ `text-primary bg-transparent ${border} border-primary/50`, 'hover:bg-primary/hover hover:border-primary', disabled, ]; case 'danger': return [ `text-danger bg-transparent ${border} border-danger/50`, 'hover:bg-danger/4 hover:border-danger', disabled, ]; case 'positive': return [ `text-positive bg-transparent ${border} border-positive/50`, 'hover:bg-positive/4 hover:border-positive', disabled, ]; case 'paper': return [`text bg-paper ${border}`, 'hover:bg-hover', disabled]; case 'white': return [ 'text-white bg-transparent border border-white', 'hover:bg-white/20', 'disabled:text-white/70 disabled:border-white/70 disabled:bg-transparent', ]; default: return [`bg-transparent ${border}`, 'hover:bg-hover', disabled]; } } function text({color}: SharedButtonStyleProps) { const disabled = 'disabled:text-disabled disabled:bg-transparent'; switch (color) { case 'primary': return [ 'text-primary bg-transparent border-transparent', 'hover:bg-primary/4', disabled, ]; case 'danger': return [ 'text-danger bg-transparent border-transparent', 'hover:bg-danger/4', disabled, ]; case 'positive': return [ 'text-positive bg-transparent border-transparent', 'hover:bg-positive/4', disabled, ]; case 'white': return [ 'text-white bg-transparent border-transparent', 'hover:bg-white/20', 'disabled:text-white/70 disabled:bg-transparent', ]; default: return ['bg-transparent border-transparent', 'hover:bg-hover', disabled]; } } function link({color}: SharedButtonStyleProps) { switch (color) { case 'primary': return ['text-primary', 'hover:underline', 'disabled:text-disabled']; case 'danger': return ['text-danger', 'hover:underline', 'disabled:text-disabled']; default: return ['text-main', 'hover:underline', 'disabled:text-disabled']; } } function contained({color, border}: SharedButtonStyleProps) { const disabled = 'disabled:text-disabled disabled:bg-disabled disabled:border-transparent disabled:shadow-none'; switch (color) { case 'primary': return [ `text-on-primary bg-primary ${border} border-primary`, 'hover:bg-primary-dark hover:border-primary-dark', disabled, ]; case 'danger': return [ `text-white bg-danger ${border} border-danger`, 'hover:bg-danger/90 hover:border-danger/90', disabled, ]; case 'chip': return [ `text-main bg-chip ${border} border-chip`, 'hover:bg-chip/90 hover:border-chip/90', disabled, ]; case 'paper': return [ `text-main bg-paper ${border} border-paper`, 'hover:bg-paper/90 hover:border-paper/90', disabled, ]; case 'white': return [ `text-black bg-white ${border} border-white`, 'hover:bg-white', disabled, ]; default: return [`bg ${border} border-background`, 'hover:bg-hover', disabled]; } }