Skip to content

Commit

Permalink
Merge pull request #7 from kakao-tech-campus-2nd-step3/feat/#4
Browse files Browse the repository at this point in the history
Feat/#4 Input, Card, Flex 공통 컴포넌트 구현
  • Loading branch information
kang-kibong authored Sep 26, 2024
2 parents 47bb08d + 4b9d974 commit 88099c5
Show file tree
Hide file tree
Showing 19 changed files with 229 additions and 19 deletions.
1 change: 0 additions & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
npx lint-staged
npx lint-staged
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint --cache 'src/**/*.{ts,tsx}'",
"tsc": "tsc --noEmit",
"format": "prettier --write --cache 'src/**/*.{ts,tsx}'",
"lint-staged": "lint-staged",
"preview": "vite preview",
Expand All @@ -18,23 +19,22 @@
"lint-staged": {
"**/*.{tsx,ts,jsx,js}": [
"eslint --fix --cache",
"prettier --write --cache"
],
"*.js": "eslint --cache --fix",
"*.{ts,tsx}": "prettier --write"
"prettier --write --cache"
]
},
"dependencies": {
"@emotion/babel-plugin": "^11.12.0",
"@emotion/react": "^11.13.3",
"@emotion/styled": "^11.13.0",
"@emotion/css": "^11.13.0",
"@tanstack/react-query": "^5.56.2",
"csstype": "^3.1.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"zustand": "^4.5.5"
},
"devDependencies": {
"@chromatic-com/storybook": "^2.0.2",
"@emotion/css": "^11.13.0",
"@eslint/js": "^9.9.0",
"@storybook/addon-essentials": "^8.3.0",
"@storybook/addon-interactions": "^8.3.0",
Expand Down
9 changes: 1 addition & 8 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
import GlobalStyles from './assets/styles';

function App() {
return (
<>
<GlobalStyles />
<h1>hello world!</h1>
</>
);
return <h1>helloWorld!</h1>;
}

export default App;
8 changes: 8 additions & 0 deletions src/assets/styles/emotion.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import '@emotion/react';
import { PalettesTypes } from './global/palettes';

declare module '@emotion/react' {
export interface Theme {
palettes: PalettesTypes;
}
}
6 changes: 6 additions & 0 deletions src/assets/styles/global/palettes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const palettes = {
white: '#fff',
borderGray: '#e4e5e8',
};

export type PalettesTypes = typeof palettes;
8 changes: 8 additions & 0 deletions src/assets/styles/theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Theme } from '@emotion/react';
import { palettes } from './global/palettes';

const theme: Theme = {
palettes,
};

export default theme;
24 changes: 24 additions & 0 deletions src/components/common/Card/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Meta, StoryObj } from '@storybook/react';
import Card from '.';

const meta: Meta<typeof Card> = {
title: 'common/Card',
component: Card,
tags: ['autodocs'],
};

export default meta;

type Story = StoryObj<typeof Card>;

export const Default: Story = {
args: {
borderRadius: '12px',
children: <h1>Hello World!</h1>,
},
render: (args) => (
<Card {...args} css={{ padding: '12px 24px' }}>
<h1>Hello World!</h1>
</Card>
),
};
22 changes: 22 additions & 0 deletions src/components/common/Card/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import styled from '@emotion/styled';
import { HTMLAttributes, ReactNode } from 'react';

interface Props extends HTMLAttributes<HTMLDivElement> {
borderRadius?: string;
children: ReactNode;
}

export default function Card({ borderRadius = '12px', children, ...rest }: Props) {
return (
<CardContainer borderRadius={borderRadius} {...rest}>
{children}
</CardContainer>
);
}

const CardContainer = styled.div<{ borderRadius: string }>`
display: inline-block;
border: 1px solid ${({ theme }) => theme.palettes.white};
box-shadow: 0px 12px 32px 0px rgba(24, 25, 28, 0.08);
border-radius: ${({ borderRadius }) => borderRadius};
`;
40 changes: 40 additions & 0 deletions src/components/common/Flex/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Meta, StoryObj } from '@storybook/react';
import Flex from '.';

const meta: Meta<typeof Flex> = {
title: 'common/Flex',
component: Flex,
tags: ['autodocs'],
};

export default meta;

type Story = StoryObj<typeof Flex>;

export const Default: Story = {
args: {
direction: 'row',
justifyContent: 'center',
alignItems: 'center',
gap: {
x: '10px',
y: '10px',
},
},
render: (args) => (
<Flex {...args}>
<div style={boxStyle}>Box 1</div>
<div style={boxStyle}>Box 2</div>
<div style={boxStyle}>Box 3</div>
</Flex>
),
};

const boxStyle = {
width: '100px',
height: '100px',
backgroundColor: 'lightblue',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
};
42 changes: 42 additions & 0 deletions src/components/common/Flex/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import styled from '@emotion/styled';
import type * as CSS from 'csstype';
import { HTMLAttributes } from 'react';

type FlexGap = {
x: string;
y: string;
};

interface FlexProps {
direction?: 'column' | 'row';
gap?: FlexGap;
justifyContent?: CSS.Properties['justifyContent'];
alignItems?: CSS.Properties['alignItems'];
}

type Props = HTMLAttributes<HTMLDivElement> & FlexProps;

export default function Flex({
direction = 'row',
gap,
justifyContent = 'start',
alignItems = 'start',
children,
...rest
}: Props) {
return (
<Container direction={direction} gap={gap} justifyContent={justifyContent} alignItems={alignItems} {...rest}>
{children}
</Container>
);
}

const Container = styled.div<FlexProps>`
width: 100%;
display: flex;
flex-direction: ${(p) => p.direction};
justify-content: ${(p) => p.justifyContent};
align-items: ${(p) => p.alignItems};
column-gap: ${(p) => p.gap?.x};
row-gap: ${(p) => p.gap?.y};
`;
20 changes: 20 additions & 0 deletions src/components/common/Input/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Meta, StoryObj } from '@storybook/react';
import Input from '.';

const meta: Meta<typeof Input> = {
title: 'common/Input',
component: Input,
tags: ['autodocs'],
};

export default meta;

type Story = StoryObj<typeof Input>;

export const Default: Story = {
args: {
label: '아이디',
placeholder: '아이디를 입력해주세요.',
},
render: (args) => <Input {...args} css={{ padding: '12px' }} />,
};
21 changes: 21 additions & 0 deletions src/components/common/Input/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { InputHTMLAttributes } from 'react';
import styled from '@emotion/styled';

interface Props extends InputHTMLAttributes<HTMLInputElement> {
label?: string;
}

export default function Input({ label, ...rest }: Props) {
return (
<>
{label && <label>{label}</label>}
<InputContainer {...rest} />
</>
);
}

const InputContainer = styled.input`
background-color: ${({ theme }) => theme.palettes.white};
border: 1px solid ${({ theme }) => theme.palettes.borderGray};
border-radius: 5px;
`;
File renamed without changes.
19 changes: 19 additions & 0 deletions src/components/providers/GlobalStylesProvider/index.provider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ReactNode } from 'react';
import { ThemeProvider } from '@emotion/react';
import GlobalStyles from './GlobalStyles';
import theme from '@assets/styles/theme';

interface Props {
children: ReactNode;
}

const GlobalStylesProvider = ({ children }: Props) => {
return (
<ThemeProvider theme={theme}>
<GlobalStyles />
{children}
</ThemeProvider>
);
};

export default GlobalStylesProvider;
6 changes: 6 additions & 0 deletions src/components/providers/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { ReactNode } from 'react';
import GlobalStylesProvider from './GlobalStylesProvider/index.provider';

export default function AppProviders({ children }: { children: ReactNode }) {
return <GlobalStylesProvider>{children}</GlobalStylesProvider>;
}
6 changes: 3 additions & 3 deletions src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.tsx';
import AppProviders from '@components/providers/index.tsx';

createRoot(document.getElementById('root')!).render(
<StrictMode>
<AppProviders>
<App />
</StrictMode>,
</AppProviders>,
);
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
"@routes/*": ["src/routes/*"],
"@utils/*": ["src/utils/*"],
"@types/*": ["src/types/*"]
}
},
"jsxImportSource": "@emotion/react"
},
"include": [
"src",
Expand Down
2 changes: 1 addition & 1 deletion vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import react from '@vitejs/plugin-react';

// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
plugins: [react({ jsxImportSource: '@emotion/react' })],
resolve: {
alias: [
{ find: '@', replacement: resolve(__dirname, 'src') },
Expand Down

0 comments on commit 88099c5

Please sign in to comment.