Skip to content

Commit

Permalink
헤더 컴포넌트 구현_Feat/#16 (#39)
Browse files Browse the repository at this point in the history
* feat: (#16) 검색 아이콘 색상(검/흰) 분리

* feat: (#16) 검색바 컴포넌트 생성

* test: (#16) 검색바 컴포넌트 크기별 테스트

* feat: (#16) 탭, 모니터용 긴 헤더 컴포넌트 생성

* test: (#16) 탭, 모니터용 긴 헤더 컴포넌트 테스트 생성

* feat: (#16) 로고, 프로젝트명 버튼 컴포넌트 생성

* test: (#16) 로고, 프로젝트명 버튼 컴포넌트 테스트 생성

* refactor: 로고 버튼으로 기존 코드 변경

* feat: (#16) 모바일 버전 메인페이지 헤더 컴포넌트 생성

* test: (#16) 모바일 버전 메인페이지 헤더 컴포넌트 테스트 생성

* feat: (#16) 모바일용 짧은 헤더 템플릿 컴포넌트 생성

- 내용을 children 프롭스로 전달받도록 구현
- 상단 고정 등 공동의 스타일 공유하기 위해 컴포넌트 제작

* test: (#16) 모바일용 짧은 헤더 템플릿 컴포넌트 테스트

* design: (#16) 검색바 버튼 커서를 포인터로 수정

* test: (#16) 스토리명 파스칼케이스로 수정

* refactor: (#15) 로고 컴포넌트 프롭스명 수정

* test: (#15) 로고 컴포넌트 프롭스명 수정에 따른 테스트 수정

* style: (#15) 코드 컨벤션에 맞게 CSS 순서 정렬

* refactor: 짧은 기본 헤더 이름 수정

- NarrowOriginHeader > NarrowMainHeader
  • Loading branch information
chsua authored Jul 14, 2023
1 parent 386fcec commit 749f850
Show file tree
Hide file tree
Showing 22 changed files with 375 additions and 10 deletions.
3 changes: 3 additions & 0 deletions frontend/src/assets/search_black.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ const meta: Meta<typeof AddButton> = {
export default meta;
type Story = StoryObj<typeof AddButton>;

export const size_S: Story = {
export const SizeS: Story = {
render: () => <AddButton size="sm" />,
};

export const size_M: Story = {
export const sizeM: Story = {
render: () => <AddButton size="md" />,
};

export const size_L: Story = {
export const sizeL: Story = {
render: () => <AddButton size="lg" />,
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ const meta: Meta<typeof HeaderTextButton> = {
export default meta;
type Story = StoryObj<typeof HeaderTextButton>;

export const defaultButton: Story = {
export const DefaultButton: Story = {
render: () => <HeaderTextButton>확 인</HeaderTextButton>,
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ const meta: Meta<typeof IconButton> = {
export default meta;
type Story = StoryObj<typeof IconButton>;

export const category: Story = {
export const Category: Story = {
render: () => <IconButton category="category" />,
};

export const back: Story = {
export const Back: Story = {
render: () => <IconButton category="back" />,
};

export const search: Story = {
export const Search: Story = {
render: () => <IconButton category="search" />,
};
2 changes: 1 addition & 1 deletion frontend/src/components/common/IconButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ButtonHTMLAttributes } from 'react';

import backIcon from '@assets/back.svg';
import categoryIcon from '@assets/category.svg';
import searchIcon from '@assets/search.svg';
import searchIcon from '@assets/search_white.svg';

import * as S from './style';

Expand Down
25 changes: 25 additions & 0 deletions frontend/src/components/common/LogoButton/LogoButton.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { Meta, StoryObj } from '@storybook/react';

import LogoButton from '.';

const meta: Meta<typeof LogoButton> = {
component: LogoButton,
decorators: [
storyFn => <div style={{ backgroundColor: 'black', height: '100px' }}>{storyFn()}</div>,
],
};

export default meta;
type Story = StoryObj<typeof LogoButton>;

export const Icon: Story = {
render: () => <LogoButton content="icon" />,
};

export const Text: Story = {
render: () => <LogoButton content="text" />,
};

export const Full: Story = {
render: () => <LogoButton content="full" />,
};
47 changes: 47 additions & 0 deletions frontend/src/components/common/LogoButton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { ButtonHTMLAttributes } from 'react';

import logo from '@assets/logo.svg';
import votogether from '@assets/projectName.svg';

import * as S from './style';

type Content = 'icon' | 'text' | 'full';

const contentCategory: { [key in Content]: { name: string; url: string } } = {
icon: {
name: '로고 아이콘',
url: logo,
},
text: {
name: 'votogether',
url: votogether,
},
full: {
name: 'votogether',
url: '',
},
};

interface LogoButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
content: Content;
}

export default function LogoButton({ content, ...rest }: LogoButtonProps) {
const src = contentCategory[content].url;
const ariaLabelText = contentCategory[content].name;

if (content === 'full') {
return (
<S.Button content={content} aria-label={ariaLabelText} {...rest}>
<img src={logo} alt="로고 아이콘" />
<img src={votogether} alt="VoTogether" />
</S.Button>
);
}

return (
<S.Button content={content} aria-label={ariaLabelText} {...rest}>
<img src={src} alt="로고 아이콘" />
</S.Button>
);
}
24 changes: 24 additions & 0 deletions frontend/src/components/common/LogoButton/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { styled } from 'styled-components';

type Content = 'icon' | 'text' | 'full';

export const Button = styled.button<{ content: Content }>`
display: flex;
align-items: center;
gap: 10px;
background-color: rgba(0, 0, 0, 0);
height: 100%;
cursor: pointer;
& :first-child {
height: 100%;
border-radius: 5px;
}
& :last-child {
height: ${props => props.content !== 'icon' && '60%'};
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { Meta, StoryObj } from '@storybook/react';

import NarrowMainHeader from '.';

const meta: Meta<typeof NarrowMainHeader> = {
component: NarrowMainHeader,
decorators: [storyFn => <div style={{ width: '576px', position: 'relative' }}>{storyFn()}</div>],
};

export default meta;
type Story = StoryObj<typeof NarrowMainHeader>;

export const Primary: Story = {
render: () => <NarrowMainHeader />,
};
14 changes: 14 additions & 0 deletions frontend/src/components/common/NarrowMainHeader/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import IconButton from '../IconButton';
import LogoButton from '../LogoButton';

import * as S from './style';

export default function NarrowMainHeader() {
return (
<S.Container>
<IconButton category="category" />
<LogoButton content="icon" />
<IconButton category="search" />
</S.Container>
);
}
22 changes: 22 additions & 0 deletions frontend/src/components/common/NarrowMainHeader/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { styled } from 'styled-components';

export const Container = styled.div`
display: flex;
align-items: center;
justify-content: space-between;
gap: 20px;
width: 100%;
height: 55px;
padding: 0 20px;
position: absolute;
top: 0;
background-color: #1f1f1f;
& :nth-child(2) {
margin-right: auto;
height: 60%;
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import type { Meta, StoryObj } from '@storybook/react';

import NarrowTemplateHeader from '.';

const meta: Meta<typeof NarrowTemplateHeader> = {
component: NarrowTemplateHeader,
decorators: [storyFn => <div style={{ width: '576px', position: 'relative' }}>{storyFn()}</div>],
};

export default meta;
type Story = StoryObj<typeof NarrowTemplateHeader>;

export const BothSideHeader: Story = {
render: () => (
<NarrowTemplateHeader>
<div style={{ width: '30px', backgroundColor: 'red' }}>예시</div>
<div style={{ width: '30px', backgroundColor: 'yellow' }}>예시</div>
</NarrowTemplateHeader>
),
};

export const ThreeComponentHeaderLeft: Story = {
render: () => (
<NarrowTemplateHeader>
<div style={{ display: 'flex', gap: '20px' }}>
<div style={{ width: '30px', backgroundColor: 'red' }}>예시</div>
<div style={{ width: '30px', backgroundColor: 'white' }}>예시</div>
</div>
<div style={{ width: '30px', backgroundColor: 'yellow' }}>예시</div>
</NarrowTemplateHeader>
),
};

export const ThreeComponentHeaderRight: Story = {
render: () => (
<NarrowTemplateHeader>
<div style={{ width: '30px', backgroundColor: 'red' }}>예시</div>
<div style={{ display: 'flex', gap: '20px' }}>
<div style={{ width: '30px', backgroundColor: 'white' }}>예시</div>
<div style={{ width: '30px', backgroundColor: 'yellow' }}>예시</div>
</div>
</NarrowTemplateHeader>
),
};
7 changes: 7 additions & 0 deletions frontend/src/components/common/NarrowTemplateHeader/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { ReactNode } from 'react';

import * as S from './style';

export default function NarrowTemplateHeader({ children }: { children: ReactNode }) {
return <S.Container>{children}</S.Container>;
}
17 changes: 17 additions & 0 deletions frontend/src/components/common/NarrowTemplateHeader/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { styled } from 'styled-components';

export const Container = styled.div`
display: flex;
align-items: center;
justify-content: space-between;
gap: 20px;
width: 100%;
height: 55px;
padding: 0 20px;
position: absolute;
top: 0;
background-color: #1f1f1f;
`;
26 changes: 26 additions & 0 deletions frontend/src/components/common/SearchBar/SearchBar.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { Meta, StoryObj } from '@storybook/react';

import SearchBar from '.';

const meta: Meta<typeof SearchBar> = {
component: SearchBar,
};

export default meta;
type Story = StoryObj<typeof SearchBar>;

export const SizeSm: Story = {
render: () => <SearchBar size="sm" />,
};

export const SizeMd: Story = {
render: () => <SearchBar size="md" />,
};

export const SizeLg: Story = {
render: () => <SearchBar size="lg" />,
};

export const SizeFree: Story = {
render: () => <SearchBar size="free" />,
};
22 changes: 22 additions & 0 deletions frontend/src/components/common/SearchBar/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { FormHTMLAttributes } from 'react';

import searchIcon from '@assets/search_black.svg';

import { Size } from '../AddButton/type';

import * as S from './style';

interface SearchBarProps extends FormHTMLAttributes<HTMLFormElement> {
size: Size | 'free';
}

export default function SearchBar({ size, ...rest }: SearchBarProps) {
return (
<S.Form size={size} {...rest}>
<S.Input type="text" />
<S.Button type="submit">
<img src={searchIcon} alt="검색버튼" />
</S.Button>
</S.Form>
);
}
47 changes: 47 additions & 0 deletions frontend/src/components/common/SearchBar/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { styled } from 'styled-components';

import { Size } from '../AddButton/type';

interface SearchBarProps {
size: Size | 'free';
}

const formSize = {
sm: '170px',
md: '250px',
lg: '400px',
};

export const Form = styled.form<SearchBarProps>`
display: flex;
align-items: center;
justify-content: space-between;
gap: 5px;
width: ${props => (props.size === 'free' ? '100%' : formSize[props.size])};
height: 36px;
padding: 5px 10px;
border-radius: 5px;
background-color: #cccccc;
color: red;
font-size: 1rem;
`;

export const Input = styled.input`
width: 100%;
height: 100%;
outline: 0;
background-color: rgba(0, 0, 0, 0);
font-size: 14px;
letter-spacing: 1px;
`;

export const Button = styled.button`
background-color: rgba(0, 0, 0, 0);
cursor: pointer;
`;
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ const meta: Meta<typeof SquareButton> = {
export default meta;
type Story = StoryObj<typeof SquareButton>;

export const color_blank: Story = {
export const ColorBlank: Story = {
render: () => <SquareButton theme="blank">확 인</SquareButton>,
};

export const color_fill: Story = {
export const ColorFill: Story = {
render: () => <SquareButton theme="fill">버 튼</SquareButton>,
};
Loading

0 comments on commit 749f850

Please sign in to comment.