diff --git a/packages/react/src/components/buttons/abstract-button.tsx b/packages/react/src/components/buttons/abstract-button.tsx index 62c3b6fb95..2ef21e2c85 100755 --- a/packages/react/src/components/buttons/abstract-button.tsx +++ b/packages/react/src/components/buttons/abstract-button.tsx @@ -1,18 +1,6 @@ +import { Theme } from '@design-elements/themes/theme'; import { focus } from '@design-elements/utils/css-state'; -import { AriaAttributes, ButtonHTMLAttributes, DetailedHTMLProps, ReactNode } from 'react'; -import styled from 'styled-components'; - -type PartialButtonProps = - Pick, HTMLButtonElement>, 'type'> - & AriaAttributes; - -export interface AbstractButtonProps extends PartialButtonProps { - label?: string; - children?: ReactNode; - disabled?: boolean; - - onClick?(): void; -} +import styled, { css, FlattenInterpolation, ThemeProps, DefaultTheme } from 'styled-components'; export const AbstractButton = styled.button<{ isMobile: boolean }>` align-items: center; @@ -46,3 +34,90 @@ export const AbstractButton = styled.button<{ isMobile: boolean }>` color: inherit; } `; + +type ButtonType = 'primary' | 'secondary' | 'tertiary' | 'destructive'; + +interface ButtonTypeStyles { + buttonType: ButtonType; + inversed?: boolean; + theme: Theme; +} + +export const getButtonTypeStyles: (props: ButtonTypeStyles) => FlattenInterpolation> = (props: ButtonTypeStyles) => css` + ${focus(props, true)}; + ${() => { + const { buttonType, theme, inversed } = props; + switch (buttonType) { + case 'primary': + return ` + background-color: ${theme.main['primary-1.1']}; + border-color: ${theme.main['primary-1.1']}; + color: ${theme.greys.white}; + + &:hover { + background-color: ${theme.main['primary-1.3']}; + border-color: ${theme.main['primary-1.3']}; + } + + &:disabled { + background-color: ${theme.main['primary-1.2']}; + border-color: ${theme.main['primary-1.2']}; + } + `; + case 'secondary': + return ` + background-color: transparent; + border-color: ${theme.main['primary-1.1']}; + color: ${theme.main['primary-1.1']}; + + &:hover { + border-color: ${theme.main['primary-1.3']}; + color: ${theme.main['primary-1.3']}; + } + + &:disabled { + border-color: ${theme.main['primary-1.2']}; + color: ${theme.main['primary-1.2']}; + } + `; + case 'tertiary': + return ` + background-color: transparent; + border-color: transparent; + color: ${theme.greys['dark-grey']}; + + &:hover { + background-color: ${theme.greys.grey}; + color: ${theme.greys.black}; + } + + &:disabled { + background-color: transparent; + color: ${theme.greys['mid-grey']}; + } + `; + case 'destructive': + // TODO change colors when updating thematization + return ` + background-color: ${inversed ? theme.greys.white : theme.notifications['error-2.1']}; + border-color: ${inversed ? theme.greys.white : theme.notifications['error-2.1']}; + color: ${inversed ? theme.notifications['error-2.1'] : theme.greys.white}; + + &:hover { + background-color: ${inversed ? theme.greys.white : '#62071b'}; + color: ${inversed ? '#62071b' : theme.greys.white}; + } + + &:disabled { + &, + &:focus, + &:hover { + background-color: ${inversed ? theme.greys.white : '#ea8da3'}; + border-color: ${inversed ? theme.greys.white : '#ea8da3'}; + color: ${inversed ? '#ea8da3' : theme.greys.white}; + } + } + `; + } + }} +`; diff --git a/packages/react/src/components/buttons/button.tsx b/packages/react/src/components/buttons/button.tsx index 7d70edefd3..d559356cb5 100644 --- a/packages/react/src/components/buttons/button.tsx +++ b/packages/react/src/components/buttons/button.tsx @@ -1,104 +1,30 @@ import { Theme } from '@design-elements/themes/theme'; -import { focus } from '@design-elements/utils/css-state'; -import React, { ReactElement } from 'react'; +import React, { ReactElement, ReactNode } from 'react'; import styled from 'styled-components'; import { useDeviceContext } from '../device-context-provider/device-context-provider'; -import { AbstractButton, AbstractButtonProps } from './abstract-button'; +import { AbstractButton, getButtonTypeStyles } from './abstract-button'; type ButtonType = 'primary' | 'secondary' | 'tertiary' | 'destructive'; type Type = 'submit' | 'button' | 'reset'; -interface ButtonProps extends AbstractButtonProps { +interface ButtonProps { /** * Visual style * @default primary */ buttonType: ButtonType; - /** - * Sets button type - * @default submit - */ - type?: Type; + children?: ReactNode; + disabled?: boolean; inversed?: boolean; + label?: string; + type?: Type; + + onClick?(): void; } const StyledButton = styled(AbstractButton)<{ theme: Theme } & ButtonProps>` - ${(props) => focus(props, true)}; - ${({ theme, buttonType, inversed }) => { - switch (buttonType) { - case 'primary': - return ` - background-color: ${theme.main['primary-1.1']}; - border-color: ${theme.main['primary-1.1']}; - color: ${theme.greys.white}; - - &:hover { - background-color: ${theme.main['primary-1.3']}; - border-color: ${theme.main['primary-1.3']}; - } - - &:disabled { - background-color: ${theme.main['primary-1.2']}; - border-color: ${theme.main['primary-1.2']}; - } - `; - case 'secondary': - return ` - background-color: transparent; - border-color: ${theme.main['primary-1.1']}; - color: ${theme.main['primary-1.1']}; - - &:hover { - border-color: ${theme.main['primary-1.3']}; - color: ${theme.main['primary-1.3']}; - } - - &:disabled { - border-color: ${theme.main['primary-1.2']}; - color: ${theme.main['primary-1.2']}; - } - `; - case 'tertiary': - return ` - background-color: transparent; - border-color: transparent; - color: ${theme.greys['dark-grey']}; - - &:hover { - background-color: ${theme.greys.grey}; - color: ${theme.greys.black}; - } - - &:disabled { - background-color: transparent; - color: ${theme.greys['mid-grey']}; - } - `; - case 'destructive': - // TODO change colors when updating thematization - return ` - background-color: ${inversed ? theme.greys.white : theme.notifications['error-2.1']}; - border-color: ${inversed ? theme.greys.white : theme.notifications['error-2.1']}; - color: ${inversed ? theme.notifications['error-2.1'] : theme.greys.white}; - - &:hover { - background-color: ${inversed ? theme.greys.white : '#62071b'}; - color: ${inversed ? '#62071b' : theme.greys.white}; - } - - &:disabled { - &, - &:focus, - &:hover { - background-color: ${inversed ? theme.greys.white : '#ea8da3'}; - border-color: ${inversed ? theme.greys.white : '#ea8da3'}; - color: ${inversed ? '#ea8da3' : theme.greys.white}; - } - } - `; - } - }} + ${getButtonTypeStyles} `; export function Button({ diff --git a/packages/react/src/components/buttons/icon-button.tsx b/packages/react/src/components/buttons/icon-button.tsx index 6acea7600e..858c26b97b 100644 --- a/packages/react/src/components/buttons/icon-button.tsx +++ b/packages/react/src/components/buttons/icon-button.tsx @@ -1,13 +1,12 @@ -import { Theme } from '@design-elements/themes/theme'; -import { focus } from '@design-elements/utils/css-state'; import React, { ReactElement } from 'react'; import styled from 'styled-components'; import { useDeviceContext } from '../device-context-provider/device-context-provider'; import { Icon, IconName } from '../icon/icon'; -import { AbstractButton, AbstractButtonProps } from './abstract-button'; +import { AbstractButton, getButtonTypeStyles } from './abstract-button'; + +type ButtonType = 'primary' | 'secondary' | 'tertiary' | 'destructive'; -type ButtonType = 'primary' | 'secondary' | 'tertiary'; type Type = 'submit' | 'button' | 'reset'; interface ButtonProps { @@ -16,11 +15,8 @@ interface ButtonProps { * @default primary */ buttonType: ButtonType; - /** - * Disables button - * @default false - */ disabled?: boolean; + inversed?: boolean; /** * Name of the desired icon (refer to icon library) */ @@ -29,75 +25,13 @@ interface ButtonProps { * Sets aria-label */ label: string; - /** - * Sets button type - * @default submit - */ type?: Type; onClick?(): void; } -interface StyledButtonProps { - isMobile: boolean; - theme: Theme; - buttonType: ButtonType; -} - -const StyledButton = styled(AbstractButton)` - ${(props) => focus(props, true)}; - ${({ theme, buttonType }) => { - switch (buttonType) { - case 'primary': - return ` - background-color: ${theme.main['primary-1.1']}; - border-color: ${theme.main['primary-1.1']}; - color: ${theme.greys.white}; - - &:hover { - background-color: ${theme.main['primary-1.3']}; - border-color: ${theme.main['primary-1.3']}; - } - - &:disabled { - background-color: ${theme.main['primary-1.2']}; - border-color: ${theme.main['primary-1.2']}; - } - `; - case 'secondary': - return ` - background-color: transparent; - border-color: ${theme.main['primary-1.1']}; - color: ${theme.main['primary-1.1']}; - - &:hover { - border-color: ${theme.main['primary-1.3']}; - color: ${theme.main['primary-1.3']}; - } - - &:disabled { - border-color: ${theme.main['primary-1.2']}; - color: ${theme.main['primary-1.2']}; - } - `; - case 'tertiary': - return ` - background-color: transparent; - border-color: transparent; - color: ${theme.greys['dark-grey']}; - - &:hover { - background-color: ${theme.greys.grey}; - color: ${theme.greys.black}; - } - - &:disabled { - background-color: transparent; - color: ${theme.greys['mid-grey']}; - } - `; - } - }} +const StyledButton = styled(AbstractButton)` + ${getButtonTypeStyles} padding: 0; width: ${({ isMobile }) => (isMobile ? '48px' : '32px')};