diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 05d14ce..1492f9f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @kimseunggyu @hwookim @Kimsj912 +* @kimseunggyu @hwookim diff --git a/.prettierrc.js b/.prettierrc.js index 6cf218e..9ad872e 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -6,7 +6,7 @@ module.exports = { trailingComma: 'all', printWidth: 120, arrowParens: 'always', - importOrder: ['^@mocks/(.*)$', '^@src/(.*)$', '^[./]'], + importOrder: ['^@mocks/(.*)$', '@src/styles/reset.css', '@src/styles/common.css', '^@src/(.*)$', '^[./]'], importOrderSeparation: true, importOrderSortSpecifiers: true, }; diff --git a/.storybook/preview.js b/.storybook/preview.js index defb2d7..0357026 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -3,8 +3,11 @@ import { initialize, mswDecorator } from 'msw-storybook-addon'; import { RouterContext } from 'next/dist/shared/lib/router-context'; import * as NextImage from 'next/image'; +import '@src/styles/reset.css'; + +import '@src/styles/common.css'; + import mockApis from '../__mocks__/apis'; -import '../src/styles/reset.css'; initialize(); diff --git a/package-lock.json b/package-lock.json index 6d4e295..d2f2c64 100644 --- a/package-lock.json +++ b/package-lock.json @@ -53,6 +53,7 @@ "msw-storybook-addon": "^1.6.3", "prettier": "^2.7.1", "start-server-and-test": "^1.14.0", + "storybook-addon-next-router": "^4.0.2", "tsconfig-paths-webpack-plugin": "^4.0.0", "typescript": "4.8.4" } @@ -28531,6 +28532,32 @@ "integrity": "sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w==", "dev": true }, + "node_modules/storybook-addon-next-router": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/storybook-addon-next-router/-/storybook-addon-next-router-4.0.2.tgz", + "integrity": "sha512-0rjGAl7HziW4ecDq+VU03H1dwkw5f6phqA+PMquPzdowNVl29ejVwVadLMGlovG6x2snaxMGxtySR2c5bwegSw==", + "dev": true, + "dependencies": { + "tslib": "2.4.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@storybook/addon-actions": "^6.0.0", + "@storybook/addons": "^6.0.0", + "@storybook/client-api": "^6.0.0", + "next": "^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/storybook-addon-next-router/node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "dev": true + }, "node_modules/stream-browserify": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", @@ -53103,6 +53130,23 @@ "integrity": "sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w==", "dev": true }, + "storybook-addon-next-router": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/storybook-addon-next-router/-/storybook-addon-next-router-4.0.2.tgz", + "integrity": "sha512-0rjGAl7HziW4ecDq+VU03H1dwkw5f6phqA+PMquPzdowNVl29ejVwVadLMGlovG6x2snaxMGxtySR2c5bwegSw==", + "dev": true, + "requires": { + "tslib": "2.4.0" + }, + "dependencies": { + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "dev": true + } + } + }, "stream-browserify": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", diff --git a/package.json b/package.json index a62f612..8145cc1 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "msw-storybook-addon": "^1.6.3", "prettier": "^2.7.1", "start-server-and-test": "^1.14.0", + "storybook-addon-next-router": "^4.0.2", "tsconfig-paths-webpack-plugin": "^4.0.0", "typescript": "4.8.4" }, diff --git a/src/components/Example/Example.stories.tsx b/src/components/Example/Example.stories.tsx new file mode 100644 index 0000000..23e325e --- /dev/null +++ b/src/components/Example/Example.stories.tsx @@ -0,0 +1,16 @@ +import { ComponentStory } from '@storybook/react'; +import React from 'react'; + +import Example from '.'; + +export default { + component: Example, + title: 'Components/Example', +}; + +const Template: ComponentStory = (args) => ; + +export const Default = Template.bind({}); +Default.args = { + title: 'Example Word', +}; diff --git a/src/components/Example/Example.style.tsx b/src/components/Example/Example.style.tsx new file mode 100644 index 0000000..cbf3c69 --- /dev/null +++ b/src/components/Example/Example.style.tsx @@ -0,0 +1,24 @@ +import styled from '@emotion/styled'; + +import theme from '../../styles/theme'; + +const StyledButton = styled.button` + background-color: ${theme.color.G8}; + color: ${theme.color.Primary1}; + border: 1px solid ${theme.color.borderPrimary}; + padding: 8px 16px; + line-height: ${theme.lineHeight.B}; + font-size: ${theme.textSize.B2}; + font-weight: ${theme.fontWeight.bold}; + font-family: ${theme.fontFamily.mainTitle}; + cursor: pointer; + transition: all 0.2s ease-in-out; + margin: 10px; + + &:hover { + background-color: ${theme.color.Primary2}; + color: ${theme.color.G8}; + } +`; + +export default StyledButton; diff --git a/src/components/Example/Example.tsx b/src/components/Example/Example.tsx new file mode 100644 index 0000000..5692b57 --- /dev/null +++ b/src/components/Example/Example.tsx @@ -0,0 +1,13 @@ +import React from 'react'; + +import StyledButton from './Example.style'; + +interface MyButtonProps { + title: string; +} + +const MyButton = ({ title }: MyButtonProps) => { + return {title}; +}; + +export default MyButton; diff --git a/src/components/Example/index.tsx b/src/components/Example/index.tsx new file mode 100644 index 0000000..80c34b2 --- /dev/null +++ b/src/components/Example/index.tsx @@ -0,0 +1 @@ +export { default } from './Example'; diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index a1f0c69..720ee34 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -3,8 +3,11 @@ import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; import type { AppProps } from 'next/app'; import { RecoilRoot } from 'recoil'; +import '@src/styles/reset.css'; + +import '@src/styles/common.css'; + import queryClient from '../configs/queryClient'; -import '../styles/reset.css'; if (process.env.NODE_ENV === 'development') { if (typeof window === 'undefined') { diff --git a/src/styles/common.css b/src/styles/common.css new file mode 100644 index 0000000..5b764cd --- /dev/null +++ b/src/styles/common.css @@ -0,0 +1,46 @@ +@font-face { + font-family: 'Pretendard-Regular'; + src: url('https://cdn.jsdelivr.net/gh/Project-Noonnu/noonfonts_2107@1.1/Pretendard-Regular.woff') format('woff'); + font-weight: 400; + font-style: normal; +} +body { + line-height: 1; + background-color: #101012; + color: #f1f3f5; +} +ol, +ul { + list-style: none; +} +blockquote, +q { + quotes: none; +} +blockquote:before, +blockquote:after, +q:before, +q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +h1 { + font-size: 20pt; + font-weight: bold; +} +h2 { + font-size: 18pt; + font-weight: medium; +} +h3 { + font-size: 16pt; + font-weight: regular; +} +p { + font-size: 14pt; + font-weight: regular; +} diff --git a/src/styles/reset.css b/src/styles/reset.css index d971da6..0827cf3 100644 --- a/src/styles/reset.css +++ b/src/styles/reset.css @@ -89,6 +89,7 @@ video { border: 0; font-size: 100%; font: inherit; + font-family: 'Pretendard-Regular', 'Noto Sans CJK KR', syne; vertical-align: baseline; } /* HTML5 display-role reset for older browsers */ @@ -105,25 +106,3 @@ nav, section { display: block; } -body { - line-height: 1; -} -ol, -ul { - list-style: none; -} -blockquote, -q { - quotes: none; -} -blockquote:before, -blockquote:after, -q:before, -q:after { - content: ''; - content: none; -} -table { - border-collapse: collapse; - border-spacing: 0; -} diff --git a/src/styles/theme.ts b/src/styles/theme.ts new file mode 100644 index 0000000..9271fe4 --- /dev/null +++ b/src/styles/theme.ts @@ -0,0 +1,57 @@ +const theme = { + color: { + // common color + G8: '#F8F9FA', + G7: '#9C9EA7', + G6: '#6E7178', + G5: '#4E5259', + G4: '#373a40', + G3: '#1E1D23', + G2: '#141517', + G1: '#101012', + Primary1: '#D2FA64', + Primary2: '#b2dd3c', + Secondary1: '#ff3d60', + Secondary2: '#e02d4d', + // specialized color + topicPrimary: '#ff7991', + topicSecondary: '#aef19d', + txtPrimary: '#f1f3f5', + txtSecondary: '#6E7178', + txtDanger: '#ff0000', + borderPrimary: '#f8f9fa', + }, + fontFamily: { + basic: 'Pretendard', + mainTitle: 'Syne', + }, + fontWeight: { + light: 300, + regular: 400, + bold: 700, + }, + textSize: { + H1: '40px', + H2: '24px', + H3: '20px', + T1: '18px', + T2: '16px', // B1과 동일 + T3: '15px', + B2: '14px', + B3: '12px', + B4: '8px', + code: '16px', + }, + lineHeight: { + H: '130%', + B: '150%', + }, + // TODO: 반응형 도입시 재정의 필요. (임시로 기준값 설정한 상태) + responsive: { + sm: '480px', + md: '768px', + lg: '1024px', + }, +} as const; + +export default theme;