Skip to content

Commit

Permalink
Set up SCSS module environment(ts, storybook) and change Spinner to…
Browse files Browse the repository at this point in the history
… classname-based styling (#1488)

* chore(d.ts): add scss module declaration

* style(eslint): add scss module pattern to eslint import order rule

* test(story): sass environment setting

* feat(spinner): change to classname-based styling

* docs(component-props): deprecated interpolation prop

* refactor(d.ts): change target module pattern

* chore(storybook): delete mock style

* refactor(spinner): rename component to element

* chore(env): enhance to support CSS modules in TS

* fix: delete unused ts interface

* chore(styles): apply temporary relative path

* style(storybook): apply tilde alias

* fix(spinner): fix xl size

* refactor(spinner): use mixin

* test(spinner): rm test cases that don't work

* test: update snapshot

* test(spinner): enhance

* test(spinner): add test case for forward ref

* chore: change code owner

* test(spinner): add test case for color prop
  • Loading branch information
sungik-choi committed Jul 13, 2023
1 parent 13fba5e commit 1eb7b1a
Show file tree
Hide file tree
Showing 18 changed files with 1,220 additions and 209 deletions.
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
/packages/bezier-react/src/components/Overlay/ @sungik-choi
/packages/bezier-react/src/components/ProgressBar/ @Dogdriip
/packages/bezier-react/src/components/SectionLabel/ @sungik-choi
/packages/bezier-react/src/components/Spinner/ @quino0627
/packages/bezier-react/src/components/Spinner/ @sungik-choi
/packages/bezier-react/src/components/Stack/ @sungik-choi
/packages/bezier-react/src/components/Status/ @sungik-choi
/packages/bezier-react/src/components/Tabs/ @sungik-choi
Expand Down
9 changes: 7 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
{
"eslint.workingDirectories": [{ "mode": "auto" }]
}
"eslint.workingDirectories": [
{
"mode": "auto"
}
],
"typescript.tsdk": "node_modules/typescript/lib"
}
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@channel.io/stylelint-config": "^1.2.0",
"@commitlint/cli": "^17.6.5",
"@commitlint/config-conventional": "^17.6.5",
"@storybook/addon-styling": "^1.3.2",
"cz-conventional-changelog": "^3.3.0",
"eslint": "^7.32.0",
"eslint-config-bezier": "workspace:*",
Expand All @@ -35,7 +36,8 @@
"stylelint": "^13.13.1",
"ts-node": "^10.9.1",
"turbo": "^1.10.3",
"typescript": "^4.9.5"
"typescript": "^4.9.5",
"typescript-plugin-css-modules": "^5.0.1"
},
"engines": {
"node": "18.15.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/bezier-react/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ module.exports = {
position: 'after',
},
{
pattern: './**/*.styled',
pattern: './**/*.+(styled|scss)',
group: 'sibling',
position: 'after',
},
Expand Down
8 changes: 8 additions & 0 deletions packages/bezier-react/.storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ module.exports = {
'@storybook/addon-toolbars',
'@storybook/addon-docs',
'@storybook/addon-backgrounds',
{
name: '@storybook/addon-styling',
options: {
sass: {
implementation: require('sass'),
},
},
},
],
features: {
postcss: false,
Expand Down
2 changes: 2 additions & 0 deletions packages/bezier-react/.storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
import BezierProvider from '~/src/providers/BezierProvider'
import { Text } from '~/src/components/Text'

import '~/src/styles/index.scss'

const FoundationKeyword = {
Light: 'light',
Dark: 'dark',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,21 +213,6 @@ exports[`Button Test > Disabled Test > Button can have disabled attribute 1`] =
`;

exports[`Button Test > Loading Test > Active prop change Button to hover style 1`] = `
.c5 {
display: inline-block;
width: 16px;
height: 16px;
border-style: solid;
border-width: 2px;
border-top-color: transparent;
border-right-color: inherit;
border-bottom-color: inherit;
border-left-color: inherit;
border-radius: 50%;
-webkit-animation: epmXAj 1s infinite linear;
animation: epmXAj 1s infinite linear;
}
.c2 {
font-size: 1.4rem;
line-height: 1.8rem;
Expand Down Expand Up @@ -355,9 +340,8 @@ exports[`Button Test > Loading Test > Active prop change Button to hover style 1
class="c4"
>
<div
class="c5"
class="Spinner s"
data-testid="bezier-react-spinner"
size="16"
/>
</div>
</button>
Expand Down
60 changes: 60 additions & 0 deletions packages/bezier-react/src/components/Spinner/Spinner.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
@mixin size($size) {
width: $size;
height: $size;
}

@layer components {
@keyframes spin {
0% {
transform: rotate(0deg);
}

100% {
transform: rotate(360deg);
}
}

.Spinner {
--bezier-spinner-color: inherit;

display: inline-block;
border-style: solid;
border-top-color: transparent;
border-right-color: var(--bezier-spinner-color);
border-bottom-color: var(--bezier-spinner-color);
border-left-color: var(--bezier-spinner-color);
border-radius: 50%;
animation: spin 1s linear infinite;

&.xl {
@include size(50px);
border-width: 4px;
}

&.l,
&.m {
border-width: 3px;
}

&.l {
@include size(24px);
}

&.m {
@include size(20px);
}

&.s,
&.xs {
border-width: 2px;
}

&.s {
@include size(16px);
}

&.xs {
@include size(12px);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,5 @@ const Template: Story<SpinnerProps> = ({ ...args }) => <Spinner {...args} />
export const Primary = Template.bind({})
Primary.args = {
size: SpinnerSize.M,
color: 'bg-black-dark',
}
55 changes: 0 additions & 55 deletions packages/bezier-react/src/components/Spinner/Spinner.styled.ts

This file was deleted.

119 changes: 39 additions & 80 deletions packages/bezier-react/src/components/Spinner/Spinner.test.tsx
Original file line number Diff line number Diff line change
@@ -1,102 +1,61 @@
import React from 'react'

import { LightFoundation } from '~/src/foundation'

import { render } from '~/src/utils/testUtils'

import Spinner, { SPINNER_TEST_ID } from './Spinner'
import type SpinnerProps from './Spinner.types'
import { SpinnerSize } from './Spinner.types'

describe('Spinner test >', () => {
let props: SpinnerProps

beforeEach(() => {
props = {}
})

const renderSpinner = (optionProps?: SpinnerProps) => render(
<Spinner {...props} {...optionProps} />,
describe('Spinner >', () => {
const renderSpinner = (props?: React.ComponentProps<typeof Spinner>) => render(
<Spinner {...props} />,
)

it('Spinner has default style', () => {
it('should render', () => {
const { getByTestId } = renderSpinner()
const renderedSpinner = getByTestId(SPINNER_TEST_ID)

expect(renderedSpinner).toHaveStyle('width: 20px;')
expect(renderedSpinner).toHaveStyle('height: 20px;')
expect(renderedSpinner).toHaveStyle('border-style: solid;')
expect(renderedSpinner).toHaveStyle('border-width: 3px;')
expect(renderedSpinner).toHaveStyle('border-radius: 50%;')
expect(renderedSpinner).toBeInTheDocument()
})

describe('Color >', () => {
it('Default color is inherited color', () => {
const { getByTestId } = renderSpinner()
const renderedSpinner = getByTestId(SPINNER_TEST_ID)

expect(renderedSpinner).toHaveStyle('border-top-color: transparent;')
expect(renderedSpinner).toHaveStyle('border-right-color: inherit;')
expect(renderedSpinner).toHaveStyle('border-bottom-color: inherit;')
expect(renderedSpinner).toHaveStyle('border-left-color: inherit;')
})

it('Spinner received SemanticNames', () => {
const targetSemanticName = 'bgtxt-blue-normal'
const { getByTestId } = renderSpinner({ color: targetSemanticName })
const renderedSpinner = getByTestId(SPINNER_TEST_ID)

expect(renderedSpinner).toHaveStyle('border-top-color: transparent;')
expect(renderedSpinner).toHaveStyle(`border-right-color: ${LightFoundation.theme[targetSemanticName]};`)
expect(renderedSpinner).toHaveStyle(`border-bottom-color: ${LightFoundation.theme[targetSemanticName]};`)
expect(renderedSpinner).toHaveStyle(`border-left-color: ${LightFoundation.theme[targetSemanticName]};`)
})
it('should render as a div by default', () => {
const { getByTestId } = renderSpinner()
const renderedSpinner = getByTestId(SPINNER_TEST_ID)
expect(renderedSpinner.tagName).toBe('DIV')
})

describe('Spinner Size >', () => {
it('Size XL', () => {
const { getByTestId } = renderSpinner({ size: SpinnerSize.XL })
const xlSpinner = getByTestId(SPINNER_TEST_ID)

expect(xlSpinner).toHaveStyle('width: 50px;')
expect(xlSpinner).toHaveStyle('height: 50px;')
expect(xlSpinner).toHaveStyle('border-width: 4px;')
})

it('Size L', () => {
const { getByTestId } = renderSpinner({ size: SpinnerSize.L })
const lSpinner = getByTestId(SPINNER_TEST_ID)

expect(lSpinner).toHaveStyle('width: 24px;')
expect(lSpinner).toHaveStyle('height: 24px;')
expect(lSpinner).toHaveStyle('border-width: 3px;')
})

it('Size M', () => {
const { getByTestId } = renderSpinner({ size: SpinnerSize.M })
const mSpinner = getByTestId(SPINNER_TEST_ID)
it('should render as a different element depending on `as` prop', () => {
const { getByTestId } = renderSpinner({ as: 'span' })
const renderedSpinner = getByTestId(SPINNER_TEST_ID)
expect(renderedSpinner.tagName).toBe('SPAN')
})

expect(mSpinner).toHaveStyle('width: 20px;')
expect(mSpinner).toHaveStyle('height: 20px;')
expect(mSpinner).toHaveStyle('border-width: 3px;')
})
it('should forward ref', () => {
const ref = React.createRef<HTMLDivElement>()
renderSpinner({ ref })
expect(ref.current).toBeInTheDocument()
})

it('Size S', () => {
const { getByTestId } = renderSpinner({ size: SpinnerSize.S })
const sSpinner = getByTestId(SPINNER_TEST_ID)
it('should receive style', () => {
const { getByTestId } = renderSpinner({ style: { color: 'red' } })
const renderedSpinner = getByTestId(SPINNER_TEST_ID)
expect(renderedSpinner).toHaveStyle('color: red')
})

expect(sSpinner).toHaveStyle('width: 16px;')
expect(sSpinner).toHaveStyle('height: 16px;')
expect(sSpinner).toHaveStyle('border-width: 2px;')
})
it('should receive class name', () => {
const { getByTestId } = renderSpinner({ className: 'test-class' })
const renderedSpinner = getByTestId(SPINNER_TEST_ID)
expect(renderedSpinner).toHaveClass('test-class')
})

it('Size XS', () => {
const { getByTestId } = renderSpinner({ size: SpinnerSize.XS })
const xsSpinner = getByTestId(SPINNER_TEST_ID)
it('should recieve color', () => {
const color = 'bg-black-lighter'
const { getByTestId } = renderSpinner({ color })
const renderedSpinner = getByTestId(SPINNER_TEST_ID)
expect(renderedSpinner).toHaveStyle(`--bezier-spinner-color: var(--${color})`)
})

expect(xsSpinner).toHaveStyle('width: 12px;')
expect(xsSpinner).toHaveStyle('height: 12px;')
expect(xsSpinner).toHaveStyle('border-width: 2px;')
})
it('should receive size', () => {
const { getByTestId } = renderSpinner({ size: SpinnerSize.M })
const renderedSpinner = getByTestId(SPINNER_TEST_ID)
expect(renderedSpinner).toHaveClass(SpinnerSize.M)
})
})
Loading

0 comments on commit 1eb7b1a

Please # to comment.