diff --git a/src/components/Button/index.tsx b/src/components/Button/index.tsx index e23d863..1b45486 100644 --- a/src/components/Button/index.tsx +++ b/src/components/Button/index.tsx @@ -1,30 +1,30 @@ +import { Spinner } from '..'; import { Wrapper } from './styles'; -type ButtonProps = Omit, 'size'> & { - color: - | 'client' - | 'productOwner' - | 'developer' - | 'admin' - | 'success' - | 'warning' - | 'error'; +type ButtonProps = { + color: 'client' | 'productOwner' | 'developer' | 'admin'; size?: 'small' | 'big'; variant?: 'primary-action' | 'secondary-action' | 'outlined' | 'text'; + type?: 'submit' | 'button' | 'reset'; iconLeft?: React.SVGProps; iconRight?: React.SVGProps; fullWidth?: boolean; + loading?: boolean; + disabled?: boolean; text: string; - onClick: () => void; + onClick?: () => void; }; const Button = ({ color, size = 'small', variant = 'text', + type = 'button', iconLeft, iconRight, fullWidth = false, + loading = false, + disabled = false, text, onClick, }: ButtonProps) => { @@ -33,14 +33,22 @@ const Button = ({ color={color} size={size} variant={variant} + type={type} iconLeft={iconLeft || undefined} iconRight={iconRight || undefined} fullWidth={fullWidth} + loading={loading} + disabled={disabled} onClick={onClick} > {iconLeft && {iconLeft}} {text} - {iconRight && {iconRight}} + {iconRight && !loading && {iconRight}} + {loading && ( + + + + )} ); }; diff --git a/src/components/Button/styles.ts b/src/components/Button/styles.ts index 0f45906..0e37b91 100644 --- a/src/components/Button/styles.ts +++ b/src/components/Button/styles.ts @@ -1,18 +1,13 @@ import styled, { css } from 'styled-components'; type WrapperProps = { - color: - | 'client' - | 'productOwner' - | 'developer' - | 'admin' - | 'success' - | 'warning' - | 'error'; + color: 'client' | 'productOwner' | 'developer' | 'admin'; size?: 'small' | 'big'; variant?: 'primary-action' | 'secondary-action' | 'outlined' | 'text'; iconLeft?: React.SVGProps; iconRight?: React.SVGProps; + loading?: boolean; + disabled?: boolean; fullWidth?: boolean; }; @@ -29,8 +24,8 @@ export const Wrapper = styled.button` align-items: center; } - ${({ iconLeft, iconRight }) => { - if (iconLeft || iconRight) + ${({ iconLeft, iconRight, loading }) => { + if (iconLeft || iconRight || loading) return css` display: flex; flex-direction: row; @@ -53,6 +48,12 @@ export const Wrapper = styled.button` margin-left: 0.5rem; } + .lds-dual-ring { + display: inline !important; + + border-width: 2px !important; + } + ${({ size }) => { switch (size) { case 'small': @@ -64,6 +65,16 @@ export const Wrapper = styled.button` width: 1rem; height: 1rem; } + + .lds-dual-ring { + width: 1rem !important; + height: 1rem !important; + + &:after { + width: 0.5rem !important; + height: 0.5rem !important; + } + } `; case 'big': return css` @@ -74,6 +85,16 @@ export const Wrapper = styled.button` width: 1.25rem; height: 1.25rem; } + + .lds-dual-ring { + width: 1.25rem !important; + height: 1.25rem !important; + + &:after { + width: 0.75rem !important; + height: 0.75rem !important; + } + } `; default: return css` @@ -84,6 +105,16 @@ export const Wrapper = styled.button` width: 1rem; height: 1rem; } + + .lds-dual-ring { + width: 1rem !important; + height: 1rem !important; + + &:after { + width: 0.5rem !important; + height: 0.5rem !important; + } + } `; } }} @@ -98,13 +129,20 @@ export const Wrapper = styled.button` width: 1.25rem; height: 1.25rem; } + + .lds-dual-ring { + width: 1.25rem; + height: 1.25rem; + } `}; - ${({ variant, color, theme }) => { + ${({ variant, color, theme, disabled }) => { switch (variant) { case 'primary-action': return css` - background: ${theme.colors[color].main}; + background: ${!disabled + ? theme.colors[color].main + : theme.colors[color].light}; color: ${theme.colors.white.main}; .icon svg path { @@ -112,57 +150,82 @@ export const Wrapper = styled.button` } &:hover { - background: ${theme.colors[color].dark}; + background: ${!disabled + ? theme.colors[color].dark + : theme.colors[color].light}; } `; case 'secondary-action': return css` background: ${theme.colors[color].light}; - color: #262628; + color: ${!disabled ? '#262628' : theme.colors[color].light}; .icon svg path { - stroke: #262628; + stroke: ${!disabled ? '#262628' : theme.colors[color].light}; } `; case 'outlined': return css` background: none; - color: ${theme.colors[color].main}; - border: 2px solid ${theme.colors[color].main}; + color: ${!disabled + ? theme.colors[color].main + : theme.colors[color].light}; + border: 2px solid + ${!disabled ? theme.colors[color].main : theme.colors[color].light}; .icon svg path { - stroke: ${theme.colors[color].main}; + stroke: ${!disabled + ? theme.colors[color].main + : theme.colors[color].light}; } &:hover { - background: ${theme.colors[color].main}; - color: ${theme.colors.white.main}; + background: ${!disabled ? theme.colors[color].main : 'none'}; + color: ${!disabled + ? theme.colors.white.main + : theme.colors[color].light}; .icon svg path { - stroke: ${theme.colors.white.main}; + stroke: ${!disabled + ? theme.colors.white.main + : theme.colors[color].light}; } } `; case 'text': return css` background: none; - color: ${theme.colors[color].main}; + color: ${!disabled + ? theme.colors[color].main + : theme.colors[color].light}; padding: 0; .icon svg path { - stroke: ${theme.colors[color].main}; + stroke: ${!disabled + ? theme.colors[color].main + : theme.colors[color].light}; } `; default: return css` background: none; - color: ${theme.colors[color].main}; + color: ${!disabled + ? theme.colors[color].main + : theme.colors[color].light}; padding: 0; .icon svg path { - stroke: ${theme.colors[color].main}; + stroke: ${!disabled + ? theme.colors[color].main + : theme.colors[color].light}; } `; } }} + + ${({ disabled }) => + disabled && + css` + cursor: default; + `} `;