Skip to content
This repository has been archived by the owner on Mar 13, 2023. It is now read-only.

Commit

Permalink
🔨 Refactor buttons with emotion
Browse files Browse the repository at this point in the history
  • Loading branch information
Kuboczoch committed May 24, 2021
1 parent 5084056 commit 418165f
Show file tree
Hide file tree
Showing 20 changed files with 236 additions and 237 deletions.
1 change: 1 addition & 0 deletions .storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module.exports = {
'@storybook/addon-links',
'@storybook/addon-viewport',
'@storybook/addon-essentials',
'storybook-addon-emotion-theme/dist/register',
{
name: '@storybook/addon-docs',
options: {
Expand Down
11 changes: 7 additions & 4 deletions .storybook/preview.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { ThemeProvider } from '@emotion/react'
import { addDecorator } from '@storybook/react'
import { withThemesProvider } from 'storybook-addon-emotion-theme'

import GlobalStyle from '../src/components/elements/Layout/GlobalStyle'
import theme from '../src/assets/theme/index'
import theme from '../src/assets/theme'

const themes = [theme]
addDecorator(withThemesProvider(themes))

addDecorator((story) => (
<ThemeProvider theme={theme}>
<>
{GlobalStyle}
{story()}
</ThemeProvider>
</>
))

const customViewports = {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"eslint-plugin-prettier": "^3.4.0",
"file-loader": "^6.2.0",
"prettier": "^2.3.0",
"storybook-addon-emotion-theme": "^2.1.1",
"typescript": "^4.2.4"
}
}
2 changes: 2 additions & 0 deletions src/assets/theme/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import shadows from './shadows'
import transitions from './transitions'

export interface ITheme {
name: string
breakpoints: typeof breakpoints
colors: typeof colors
constants: typeof constants
Expand All @@ -17,6 +18,7 @@ export interface ITheme {
}

const theme = {
name: 'Default theme',
breakpoints,
colors,
constants,
Expand Down
5 changes: 3 additions & 2 deletions src/assets/theme/palette.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import colors from './colors'
import colors, { TColor } from './colors'

export type TPalletColor = 'primary' | 'secondary'
export type TPalletColor = TColor | 'primary' | 'secondary'

const palette: {
[index in TPalletColor]: string
} = {
...colors,
primary: colors.apple,
secondary: colors.dodgerBlue
}
Expand Down
5 changes: 1 addition & 4 deletions src/components/elements/Button/ButtonText.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import styled from '@emotion/styled'

import theme from '../../../assets/theme'
import { includeVariant, TIncludeVariantProps } from './variants'
import { changeOpacityOnLoading } from './LoaderContainer'

const ButtonText = styled('span')<TIncludeVariantProps & { isLoading?: boolean }>`
const ButtonText = styled('span')<{ isLoading?: boolean }>`
font-weight: bold;
font-size: 16px;
line-height: 25px;
Expand All @@ -13,8 +12,6 @@ const ButtonText = styled('span')<TIncludeVariantProps & { isLoading?: boolean }
transition: all ${theme.transitions.normal};
${(props) => props.isLoading && changeOpacityOnLoading};
${(props) => includeVariant(props, 'text')};
`

export default ButtonText
38 changes: 0 additions & 38 deletions src/components/elements/Button/README.md

This file was deleted.

10 changes: 6 additions & 4 deletions src/components/elements/Button/StyledButton.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import styled from '@emotion/styled'

import { includeVariant, TIncludeVariantProps } from './variants'
import { colorStates } from './variants/_colorVariants'

const StyledButton = styled('div')<TIncludeVariantProps & { iconAlign?: 'left' | 'right' }>`
const StyledButton = styled('div')<{
disabled?: boolean
iconAlign?: 'left' | 'right'
colorStates: colorStates
}>`
position: relative;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
user-select: none;
flex-direction: ${(props) => (props.iconAlign === 'left' ? 'row' : 'row-reverse')};
${(props) => includeVariant(props, 'button')};
`

export default StyledButton
26 changes: 15 additions & 11 deletions src/components/elements/Button/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
import React from 'react'
import React, { useMemo } from 'react'
import Link, { LinkProps } from 'next/link'

import { colorStates } from './variants/_colors'
import { possibleVariants } from './variants'
import variants, { possibleVariants } from './variants'

import ButtonText from './ButtonText'
import IconContainer from './IconContainer'
import StyledButton from './StyledButton'
import StyledLink from './StyledLink'
import LoaderContainer from './LoaderContainer'
import colorVariants, { colorStates } from './variants/_colorVariants'

interface IButtonProps {
children?: null
title?: React.ReactNode
icon?: React.ReactNode
iconAlign?: 'left' | 'right'
rounded?: boolean
variant?: possibleVariants
colorStates?: colorStates
link?: LinkProps
Expand All @@ -35,20 +32,28 @@ interface IButtonProps {
* />
**/
const Button = ({ title, variant = 'primary', ...props }: IButtonProps) => {
const Variant = useMemo(() => {
return variants[variant]
}, [variant])

const ButtonComponent = () => (
<StyledButton variant={variant} {...props} {...props.buttonProps}>
<Variant.Button
{...props}
{...props.buttonProps}
colorStates={props.colorStates || colorVariants[variant]}
>
<LoaderContainer isLoading={props.isLoading}>{props.loader}</LoaderContainer>
{props.icon && (
<IconContainer iconAlign={props.iconAlign} disableMargin={!title} {...props}>
{props.icon}
</IconContainer>
)}
{title && (
<ButtonText variant={variant} {...props} {...props.textProps}>
<Variant.Text {...props} {...props.textProps}>
{title}
</ButtonText>
</Variant.Text>
)}
</StyledButton>
</Variant.Button>
)

if (props.link) {
Expand All @@ -69,7 +74,6 @@ const defaultProps: IButtonProps = {
icon: null,
iconAlign: 'right',
variant: 'primary',
rounded: false,
link: undefined,
loader: null,
isLoading: false,
Expand Down
10 changes: 9 additions & 1 deletion src/components/elements/Button/variants/_colorVariants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { colorStates } from './_colors'
import { TPalletColor } from '../../../../assets/theme/palette'

export type colorStates = {
unset: TPalletColor
hover: TPalletColor
active: TPalletColor
focus: TPalletColor
disabled: TPalletColor
}

interface colorVariant {
[key: string]: colorStates
Expand Down
25 changes: 0 additions & 25 deletions src/components/elements/Button/variants/_colors.ts

This file was deleted.

55 changes: 13 additions & 42 deletions src/components/elements/Button/variants/index.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,21 @@
import { colorStates } from './_colors'
import colorVariants from './_colorVariants'
import StyledButton from '../StyledButton'
import ButtonText from '../ButtonText'

import primary from './primary'
import secondary from './secondary'
import transparent from './transparent'
import PrimaryStyledButton from './primary/PrimaryStyledButton'
import PrimaryButtonText from './primary/PrimaryButtonText'

export interface variantProps {
color: colorStates
disabled?: boolean
}

export type possibleVariants = 'primary' | 'secondary' | 'transparent'

const variants = (props: {
colorStates?: colorStates
}): { [index in possibleVariants]: { button?: any; text?: any } } => ({
primary: primary({
color: {
...colorVariants.primary,
...props.colorStates
}
}),
secondary: secondary({
color: {
...colorVariants.secondary,
...props.colorStates
}
}),
transparent: transparent({
color: {
...colorVariants.transparent,
...props.colorStates
}
})
})
export type possibleVariants = 'primary'

export type TIncludeVariantProps = {
colorStates?: colorStates
variant: possibleVariants
type TVariant = {
Button: typeof StyledButton
Text: typeof ButtonText
}

export const includeVariant = (
props: { colorStates?: colorStates; variant: possibleVariants },
element: string
) => {
return variants(props)[props.variant][element]
const variants: { [index in possibleVariants]: TVariant } = {
primary: {
Button: PrimaryStyledButton,
Text: PrimaryButtonText
}
}

export default variants
39 changes: 0 additions & 39 deletions src/components/elements/Button/variants/primary.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import styled from '@emotion/styled'

import ButtonText from '../../ButtonText'

const PrimaryButtonText = styled(ButtonText)`
color: ${(props) => props.theme.palette['white']};
`

export default PrimaryButtonText
Loading

0 comments on commit 418165f

Please sign in to comment.