Skip to content

Commit

Permalink
feat #92 - Address PR comments
Browse files Browse the repository at this point in the history
  • Loading branch information
sam-dassana committed Oct 3, 2020
1 parent ac64fca commit 7e8aba6
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 107 deletions.
25 changes: 16 additions & 9 deletions .storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport'
import isChromatic from 'chromatic/isChromatic'
import { Story } from '@storybook/react/types-6-0'
import { StoryContext } from '@storybook/addons'
import { ThemesType } from '../src/components/assets/styles/themes'
import { withCssResources } from '@storybook/addon-cssresources'
import {
convert,
Expand All @@ -19,6 +20,8 @@ import {
} from '@storybook/theming'
import React, { FC, ReactNode, useEffect } from 'react'

const { dark, light } = ThemesType

const useStyles = createUseStyles({
storyContainer: {
display: 'flex'
Expand Down Expand Up @@ -68,6 +71,7 @@ interface StoryWrapperProps {
children: ReactNode
dark?: boolean
}

/*
This wrapper does two things:
1. Adds padding to the story since it was removed from .sb-show-main in ./index.css
Expand All @@ -88,7 +92,7 @@ const StoryWrapper: FC<StoryWrapperProps> = ({

const ThemeWrapper = (
ComponentStory: Story,
{ globals: { theme = 'light' } }: StoryContext
{ globals: { theme = light } }: StoryContext
) => {
const classes = useStyles()

Expand All @@ -102,14 +106,16 @@ const ThemeWrapper = (
<ThemeProvider theme={convert(themes.light)}>
{/* @ts-ignore */}
<ThemeBlock side='left'>
<StoryWrapper>{<ComponentStory />}</StoryWrapper>
<StoryWrapper>
<ComponentStory />
</StoryWrapper>
</ThemeBlock>
</ThemeProvider>
<ThemeProvider theme={convert(themes.dark)}>
{/* @ts-ignore */}
<ThemeBlock side='right'>
<StoryWrapper dark={true}>
{<ComponentStory />}
<StoryWrapper dark>
<ComponentStory />
</StoryWrapper>
</ThemeBlock>
</ThemeProvider>
Expand All @@ -122,8 +128,8 @@ const ThemeWrapper = (
<ThemeProvider theme={convert(themes[theme])}>
<Global styles={createReset} />
<ThemedSetRoot />
<StoryWrapper dark={theme === 'dark'}>
{<ComponentStory />}
<StoryWrapper dark={theme === dark}>
<ComponentStory />
</StoryWrapper>
</ThemeProvider>
)
Expand All @@ -133,14 +139,15 @@ const ThemeWrapper = (

export const globalTypes = {
theme: {
defaultValue: isChromatic() ? 'side-by-side' : 'light',
/* Setting side-by-side as default for chromatic allows for visual regression testing on both dark and light themed stories. */
defaultValue: isChromatic() ? 'side-by-side' : light,
description: 'Global theme for components',
name: 'Theme',
toolbar: {
icon: 'circlehollow',
items: [
{ icon: 'circlehollow', title: 'light', value: 'light' },
{ icon: 'circle', title: 'dark', value: 'dark' },
{ icon: 'circlehollow', title: light, value: light },
{ icon: 'circle', title: dark, value: dark },
{
icon: 'sidebar',
title: 'side by side',
Expand Down
9 changes: 5 additions & 4 deletions src/components/Input/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,20 @@ import { createUseStyles } from 'react-jss'
import { generateInputStyles } from './utils'
import { getDataTestAttributeProp } from '../utils'
import Skeleton from '../Skeleton'
import { ThemesType } from '../assets/styles/themes'
import {
defaultFieldWidth,
fieldErrorStyles
} from '../assets/styles/styleguide'
import React, { FC } from 'react'

const errorAnimationKeyFrames = fieldErrorStyles['@global']
const { dark, light } = ThemesType

const useStyles = createUseStyles({
'@global': {
...errorAnimationKeyFrames,
'.dark input': generateInputStyles('dark'),
input: generateInputStyles('light')
...fieldErrorStyles['@global'],
[`.${dark} input`]: generateInputStyles(dark),
input: generateInputStyles(light)
},
container: {
width: props => (props.fullWidth ? '100%' : defaultFieldWidth)
Expand Down
47 changes: 5 additions & 42 deletions src/components/Input/utils.ts
Original file line number Diff line number Diff line change
@@ -1,48 +1,11 @@
import { fadeColor } from '../utils'
import { fieldErrorStyles } from '../assets/styles/styleguide'
import { dassanaBlues, dassanaGrays } from '../assets/styles/colors'
import {
generateThemeVars,
PaletteType,
ThemesType
} from '../assets/styles/themes'

export const generateInputCSSVals = ({
background,
primary,
text
}: PaletteType) => {
const base = {
bgColor: background,
borderColor: dassanaGrays[6],
color: text.primary
}

const disabled = {
bgColor: dassanaGrays[3],
color: text.disabled
}

const hover = {
borderColor: dassanaBlues[5]
}

const focus = {
...hover,
boxShadow: `0px 0px 4px ${fadeColor(primary, 50)}`
}

const placeholder = {
color: text.disabled
}

return { base, disabled, focus, hover, placeholder }
}
import { generalColors } from '../assets/styles/baseStyles'
import { ThemesType } from '../assets/styles/themes'

export const generateInputStyles = (themeType: ThemesType) => {
const { base, disabled, focus, hover, placeholder } = generateInputCSSVals(
generateThemeVars(themeType)
)
const { base, disabled, focus, hover, placeholder } = generalColors[
themeType
]

return {
'&.ant-input': {
Expand Down
44 changes: 44 additions & 0 deletions src/components/assets/styles/baseStyles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { ColorManipulationTypes, manipulateColor } from '../../utils'
import { dassanaBlues, dassanaGrays } from './colors'
import { getThemePalette, ThemePalette, ThemesType } from './themes'

export const generateBaseStyles = ({
background,
primary,
text
}: ThemePalette) => {
const base = {
bgColor: background,
borderColor: dassanaGrays[6],
color: text.primary
}

const disabled = {
bgColor: dassanaGrays[3],
color: text.disabled
}

const hover = {
borderColor: dassanaBlues[5]
}

const focus = {
...hover,
boxShadow: `0px 0px 4px ${manipulateColor(
primary,
50,
ColorManipulationTypes.fade
)}`
}

const placeholder = {
color: text.disabled
}

return { base, disabled, focus, hover, placeholder }
}

export const generalColors = {
[ThemesType.dark]: generateBaseStyles(getThemePalette(ThemesType.dark)),
[ThemesType.light]: generateBaseStyles(getThemePalette(ThemesType.light))
}
23 changes: 12 additions & 11 deletions src/components/assets/styles/themes.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import { dassanaBlue, dassanaGrays, dassanaReds, dassanaWhite } from './colors'

interface TextColorType {
disabled: string
primary: string
}
export interface PaletteType {
export interface ThemePalette {
background: string
primary: string
error: string
text: TextColorType
text: { disabled: string; primary: string }
}

export const light: PaletteType = {
export const lightPalette: ThemePalette = {
background: dassanaWhite,
error: dassanaReds[6],
primary: dassanaBlue,
Expand All @@ -21,7 +17,7 @@ export const light: PaletteType = {
}
}

export const dark: PaletteType = {
export const darkPalette: ThemePalette = {
background: dassanaGrays[9],
error: dassanaReds[6],
primary: dassanaBlue,
Expand All @@ -31,8 +27,13 @@ export const dark: PaletteType = {
}
}

const themes = { dark, light }
export enum ThemesType {
dark = 'dark',
light = 'light'
}

const { dark, light } = ThemesType

export type ThemesType = keyof typeof themes
const themes = { [dark]: darkPalette, [light]: lightPalette }

export const generateThemeVars = (theme: ThemesType) => themes[theme]
export const getThemePalette = (theme: ThemesType) => themes[theme]
40 changes: 15 additions & 25 deletions src/components/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import Color from 'color'
import {
fadeColor,
ColorManipulationTypes,
getDataTestAttributeProp,
lightenOrDarkenColor,
manipulateColor,
TAG
} from './utils'

Expand All @@ -28,53 +28,43 @@ describe('getDataTestAttributeProp', () => {
describe('Color utils', () => {
const mockColor = 'hsl(100, 50%, 50%)'
const mockPercent = 50
const { darken, fade, lighten } = ColorManipulationTypes

describe('lightenOrDarkenColor', () => {
it('should lighten the input color by given percentage if colorChangeType is not provided', () => {
const mockLightenedColor = lightenOrDarkenColor(
describe('manipulateColor', () => {
it('should lighten the input color by given percentage for argument type lighten', () => {
const mockLightenedColor = manipulateColor(
mockColor,
mockPercent
mockPercent,
lighten
)

expect(mockLightenedColor).toBe(Color('hsl(100, 50%, 75%)').hex())
})

it('should darken the input color by given percentage if colorChangeType is provided as "dark"', () => {
const mockDarkenedColor = lightenOrDarkenColor(
it('should darken the input color by given percentage for argument type darken', () => {
const mockDarkenedColor = manipulateColor(
mockColor,
mockPercent,
'dark'
darken
)

expect(mockDarkenedColor).toBe(Color('hsl(100, 50%, 25%)').hex())
})

it('should throw an error if percent value is out of bounds', () => {
expect(() => {
lightenOrDarkenColor(mockColor, -1)
}).toThrow()

expect(() => {
lightenOrDarkenColor(mockColor, 101)
}).toThrow()
})
})

describe('fadeColor', () => {
it('should fade color by given percentage', () => {
it('should fade the input color by given percentage for argument type fade', () => {
const mockColor = 'rgba(10, 10, 10, 0.8)'
const mockFadedColor = fadeColor(mockColor, mockPercent)
const mockFadedColor = manipulateColor(mockColor, mockPercent, fade)

expect(mockFadedColor).toBe('rgba(10, 10, 10, 0.4)')
})

it('should throw an error if percent value is out of bounds', () => {
expect(() => {
fadeColor(mockColor, -1)
manipulateColor(mockColor, -1, lighten)
}).toThrow()

expect(() => {
fadeColor(mockColor, 101)
manipulateColor(mockColor, 101, darken)
}).toThrow()
})
})
Expand Down
33 changes: 17 additions & 16 deletions src/components/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,34 +31,35 @@ const getRgba = (color: string, a: number) => {
return `rgba(${r}, ${g}, ${b}, ${a})`
}

enum LigtenOrDarkenType {
light,
dark
export enum ColorManipulationTypes {
darken = 'darken',
fade = 'fade',
lighten = 'lighten'
}

export const lightenOrDarkenColor = (
export const manipulateColor = (
color: string,
percent: number,
colorChangeType?: keyof typeof LigtenOrDarkenType
colorChangeType: ColorManipulationTypes
) => {
if (percent < 0 || percent > 100)
throw new Error('please provide a valid percentage')

const clr = Color(color)

const changedClr =
colorChangeType === 'dark'
? clr.darken(percent / 100)
: clr.lighten(percent / 100)
const ratio = percent / 100

return changedClr.hex()
}
switch (colorChangeType) {
case ColorManipulationTypes.darken:
return clr.darken(ratio).hex()

export const fadeColor = (color: string, fadePercent: number) => {
if (fadePercent < 0 || fadePercent > 100)
throw new Error('please provide a valid percentage')
case ColorManipulationTypes.fade: {
const fadedColor = clr.fade(ratio)

const fadedColor = Color(color).fade(fadePercent / 100)
return getRgba(fadedColor.hex(), fadedColor.alpha())
}

return getRgba(fadedColor.hex(), fadedColor.alpha())
case ColorManipulationTypes.lighten:
return clr.lighten(ratio).hex()
}
}

0 comments on commit 7e8aba6

Please sign in to comment.