Skip to content

Commit

Permalink
Merge pull request #8 from makevook/design-system
Browse files Browse the repository at this point in the history
[Feature] 디자인 시스템 기반 컴포넌트 일부 구현
  • Loading branch information
hin6150 authored May 18, 2024
2 parents d052773 + 24c8429 commit cea3dd8
Show file tree
Hide file tree
Showing 40 changed files with 1,877 additions and 498 deletions.
2 changes: 1 addition & 1 deletion apps/web/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const withVanillaExtract = createVanillaExtractPlugin()

/** @type {import('next').NextConfig} */
const nextConfig = {
transpilePackages: ['@vook-client/ui'],
transpilePackages: ['@vook-client/design-system'],
compiler: {
styledComponents: true,
},
Expand Down
2 changes: 1 addition & 1 deletion apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"@vanilla-extract/recipes": "^0.5.2",
"@vanilla-extract/sprinkles": "^1.6.1",
"@vook-client/api": "*",
"@vook-client/ui": "*",
"@vook-client/design-system": "*",
"next": "^14.1.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
3 changes: 2 additions & 1 deletion apps/web/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Metadata } from 'next'

import ReactQueryProvider from '@/providers/ReactQueryProvider'
import { pretendard } from '@/styles/fonts'

export const metadata: Metadata = {
title: 'Create Next App',
Expand All @@ -14,7 +15,7 @@ const RootLayout = ({
}>) => {
return (
<html lang="kr">
<body>
<body className={pretendard.className}>
<ReactQueryProvider>{children}</ReactQueryProvider>
</body>
</html>
Expand Down
3 changes: 2 additions & 1 deletion apps/web/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client'

import { Button } from '@vook-client/ui'
import { Button, Text } from '@vook-client/design-system'

import { TestComponent } from '@/components/TestComponent'

Expand All @@ -11,6 +11,7 @@ const Home = () => {
return (
<main>
Hello world!
<Text>프리텐다드</Text>
<TestComponent />
<Button>Button</Button>
<h1>API_URL: {API_URL}</h1>
Expand Down
Binary file added apps/web/src/styles/PretendardVariable.woff2
Binary file not shown.
7 changes: 7 additions & 0 deletions apps/web/src/styles/fonts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import localFont from 'next/font/local'

export const pretendard = localFont({
src: './PretendardVariable.woff2',
display: 'swap',
weight: '45 920',
})
4 changes: 2 additions & 2 deletions apps/workshop/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ function getAbsolutePath(value: string): any {
const config: StorybookConfig = {
stories: [
{
directory: '../../../packages/ui/src/**',
titlePrefix: 'UI',
directory: '../../../packages/design-system/src/**',
titlePrefix: 'Vook-Design-System',
files: '*.stories.*',
},
{
Expand Down
2 changes: 2 additions & 0 deletions apps/workshop/.storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import './storybook.css'

const preview = {
parameters: {
controls: {
Expand Down
36 changes: 36 additions & 0 deletions apps/workshop/.storybook/storybook.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
@import url('https://cdn.jsdelivr.net/gh/orioncactus/[email protected]/dist/web/static/pretendard-dynamic-subset.min.css');

* {
font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
}

.storybook-list {
display: flex;
flex-direction: column;
gap: 10px;
padding: 0;
margin: 0;
list-style: none;
}

.storybook-subtitle {
margin-bottom: 8px;
color: rgb(157, 157, 157);
font-weight: 700;
}

.navy-background {
background-color: #0e0933;
}

.default-padding {
padding: 50px;
}

.section-wrapper {
width: 1280px;
}

#storybook-root {
position: relative;
}
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,8 @@
"workspaces": [
"apps/*",
"packages/*"
]
],
"dependencies": {
"@testing-library/user-event": "^14.5.2"
}
}
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "@vook-client/ui",
"name": "@vook-client/design-system",
"version": "0.0.0",
"private": true,
"exports": "./src/index.ts",
"main": "./src",
"scripts": {
"lint": "eslint . --max-warnings 0"
},
Expand Down
87 changes: 87 additions & 0 deletions packages/design-system/src/components/Button/Button.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { recipe, RecipeVariants } from '@vanilla-extract/recipes'

import { vars } from '../../styles/global.css'

export const button = recipe({
base: {
border: 'none',
borderRadius: 6,
},
variants: {
size: {
large: {
height: 48,
padding: '12px 26px',
},
middle: {
height: 40,
padding: '8px 16px',
},
small: {
height: 34,
padding: '8px 14px',
},
mini: {
height: 30,
padding: '6px 10px',
borderRadius: 4,
},
},
filled: {
true: {
backgroundColor: vars.colors['semantic-primary-normal'],
color: vars.colors['common-white'],
},
false: {
backgroundColor: 'transparent',
borderWidth: 1,
borderStyle: 'solid',
},
},
blueLine: {
true: {
borderColor: vars.colors['semantic-primary-normal'],
},
false: {
borderColor: vars.colors['semantic-line-normal'],
},
},
disabled: {
true: {
borderColor: vars.colors['palette-gray-100'],
':hover': {
cursor: 'not-allowed',
},
},
false: {
':hover': {
cursor: 'pointer',
},
},
},
},

compoundVariants: [
{
variants: {
filled: true,
disabled: true,
},
style: {
backgroundColor: vars.colors['palette-gray-100'],
color: vars.colors['semantic-label-disabled'],
},
},
{
variants: {
filled: false,
disabled: true,
},
style: {
color: vars.colors['semantic-label-disabled'],
},
},
],
})

export type ButtonVariants = RecipeVariants<typeof button>
46 changes: 46 additions & 0 deletions packages/design-system/src/components/Button/Button.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'

import { Button } from '.'

describe('Button Test', () => {
it('Button은 정상적으로 렌더링된다.', () => {
render(<Button>Button</Button>)

expect(
screen.getByRole('button', {
name: /Button/i,
}),
).toBeInTheDocument()
})

it('Button 클릭 시 onClick 함수가 실행된다.', async () => {
// given
const onClick = vi.fn()
render(<Button onClick={onClick}>Button</Button>)

// when
const button = screen.getByRole('button')
await userEvent.click(button)

// then
expect(onClick).toBeCalledTimes(1)
})

it('Button은 disabled 상태일 때 클릭되지 않는다.', async () => {
// given
const onClick = vi.fn()
render(
<Button onClick={onClick} disabled>
Button
</Button>,
)

// when
const button = screen.getByRole('button')
await userEvent.click(button)

// then
expect(onClick).not.toBeCalled()
})
})
126 changes: 126 additions & 0 deletions packages/design-system/src/components/Button/Button.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import type { Meta, StoryObj } from '@storybook/react'

import { Button, ButtonProps } from './Button'

const BUTTON_SIZES: Array<ButtonProps['size']> = [
'large',
'middle',
'small',
'mini',
]

const meta = {
title: 'Button',
component: Button,
tags: ['autodocs'],
args: {
children: 'Button',
size: 'large',
filled: true,
blueLine: true,
disabled: false,
},
argTypes: {
children: { control: 'text', description: '버튼 텍스트' },
size: {
options: BUTTON_SIZES,
control: { type: 'select' },
description: '버튼 크기',
},
filled: { control: 'boolean', description: '버튼 색상 채움 여부' },
blueLine: {
control: 'boolean',
description: '버튼 테두리 여부',
},
disabled: {
control: 'boolean',
description: '버튼 비활성화 여부',
},
},
} satisfies Meta<typeof Button>

export default meta

type Story = StoryObj<typeof Button>

export const Playground: Story = {}

export const Size: Story = {
argTypes: {
size: {
table: {
disable: true,
},
},
},
render: (props) => {
return (
<ul className="storybook-list">
{BUTTON_SIZES.map((size) => (
<li key={size}>
<p className="storybook-subtitle">{size}</p>
<Button {...props} size={size}>
{props.children}
</Button>
</li>
))}
</ul>
)
},
}

export const Type: Story = {
argTypes: {
filled: {
table: {
disable: true,
},
},
blueLine: {
table: {
disable: true,
},
},
disabled: {
table: {
disable: true,
},
},
},
render: (props) => {
return (
<ul className="storybook-list">
<li>
<p className="storybook-subtitle">Filled</p>
<Button {...props} filled>
{props.children}
</Button>
</li>
<li>
<p className="storybook-subtitle">Filled Disabled</p>
<Button {...props} filled disabled>
{props.children}
</Button>
</li>
<li>
<p className="storybook-subtitle">Blue Line</p>
<Button {...props} filled={false} blueLine>
{props.children}
</Button>
</li>
<li>
<p className="storybook-subtitle">No Blue Line</p>
<Button {...props} filled={false}>
{props.children}
</Button>
</li>
<li>
<p className="storybook-subtitle">Disabled</p>
<Button {...props} filled={false} disabled>
{props.children}
</Button>
</li>
</ul>
)
},
}
Loading

0 comments on commit cea3dd8

Please sign in to comment.