Skip to content

Commit

Permalink
[Feature] Header 컴포넌트 구현 (#167)
Browse files Browse the repository at this point in the history
* rename: 로띠 폴더명 변경

* feat: gdsc logo 아이콘 wowds-icons 패키지에 추가

* chore: gdsc logo 아이콘 색상 변경

* feat: Header 컴포넌트 구현

* docs: Header 컴포넌트 스토리 작성

* feat: 헤더 컴포넌트 빌드 설정 추가

* feat: wow-ui 스타일 변경사항 반영

* fix: Header 컴포넌트 a11y color contrast 테스트 비활성화

* chore: 스토리북 variant prop options 지정 위치 수정

* chore: role="heading", aria-level 대신 시맨틱 태그로 수정

* feat: wow-tokens 추가된 헤더 타이포 추가

* feat: wow-theme textStyles에 추가된 헤더 타이포 추가

* chore: 추가된 타이포 헤더에 적용

* chore: panda codegen 변경사항 반영

* docs: Header 컴포넌트 changeset 작성
  • Loading branch information
ghdtjgus76 authored Oct 13, 2024
1 parent 7b19f05 commit b7f51d2
Show file tree
Hide file tree
Showing 13 changed files with 897 additions and 3 deletions.
8 changes: 8 additions & 0 deletions .changeset/slimy-mice-tap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"wowds-tokens": patch
"wowds-icons": patch
"wowds-theme": patch
"wowds-ui": patch
---

Header 컴포넌트를 추가합니다.
4 changes: 3 additions & 1 deletion apps/wow-docs/styled-system/types/prop-type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,9 @@ export interface UtilityValues {
| "body3"
| "label1"
| "label2"
| "label3";
| "label3"
| "header1"
| "header2";
}

type WithColorOpacityModifier<T> = T extends string ? `${T}/${string}` : T;
Expand Down
51 changes: 51 additions & 0 deletions packages/wow-icons/src/component/GdscLogo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { forwardRef } from "react";

import type { IconProps } from "@/types/Icon.ts";

const GdscLogo = forwardRef<SVGSVGElement, IconProps>(
(
{ className, width = "49", height = "24", viewBox = "0 0 49 24", ...rest },
ref
) => {
return (
<svg
aria-label="gdsc-logo icon"
className={className}
fill="none"
height={height}
ref={ref}
viewBox={viewBox}
width={width}
xmlns="http://www.w3.org/2000/svg"
{...rest}
>
<g clipPath="url(#clip0_2093_1197)">
<path
d="M11.6948 12.0594L19.6432 7.40217C21.5086 6.3148 22.1575 3.89388 21.0828 1.98586C20.0082 0.0778397 17.6155 0.558167 15.7298 0.529199L1.98242 8.55108L11.6948 12.0594Z"
fill="#EA4335"
/>
<path
d="M17.6764 23.9997C19.0349 23.9997 20.3529 23.2816 21.0625 22.0096C22.1372 20.1221 21.5086 17.7012 19.6229 16.5933L5.87549 8.57144C4.01006 7.48407 1.61744 8.12008 0.522517 10.0281C0.552134 11.9156 0.0764355 14.3365 1.96214 15.4444L15.7096 23.4663C16.3381 23.8151 17.0275 23.9997 17.6764 23.9997Z"
fill="#4285F4"
/>
<path
d="M31.3633 23.9999C32.0324 23.9999 32.7015 23.8358 33.3098 23.4665L47.0572 15.4446L37.4867 11.8953L29.4167 16.614C27.5513 17.7014 26.9024 20.1223 27.9771 22.0303C28.6868 23.2818 30.0047 23.9999 31.3633 23.9999Z"
fill="#FBBC04"
/>
<path
d="M45.0897 15.9572C46.4482 15.9572 47.7662 15.2392 48.4758 13.9877C49.5505 12.1002 48.9219 9.67923 47.0362 8.57135L33.3091 0.549463C31.4437 0.537903 29.051 0.0981031 27.9561 2.00612C26.8815 3.89362 27.51 6.31455 29.3957 7.42243L43.1431 15.4443C43.7514 15.7931 44.4206 15.9572 45.0897 15.9572Z"
fill="#0F9D58"
/>
</g>
<defs>
<clipPath id="clip0_2093_1197">
<rect fill="white" height={height} width={width} />
</clipPath>
</defs>
</svg>
);
}
);

GdscLogo.displayName = "GdscLogo";
export default GdscLogo;
1 change: 1 addition & 0 deletions packages/wow-icons/src/component/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export { default as Check } from "./Check.tsx";
export { default as Close } from "./Close.tsx";
export { default as DownArrow } from "./DownArrow.tsx";
export { default as Edit } from "./Edit.tsx";
export { default as GdscLogo } from "./GdscLogo.tsx";
export { default as GreenAvatar } from "./GreenAvatar.tsx";
export { default as Help } from "./Help.tsx";
export { default as LeftArrow } from "./LeftArrow.tsx";
Expand Down
13 changes: 13 additions & 0 deletions packages/wow-icons/src/svg/gdsc-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions packages/wow-theme/src/tokens/typography.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,10 @@ export const textStyles = defineTextStyles({
label3: {
value: typography.label3,
},
header1: {
value: typography.header1,
},
header2: {
value: typography.header2,
},
});
12 changes: 12 additions & 0 deletions packages/wow-tokens/src/typography.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,15 @@ export const label3 = {
lineHeight: "100%",
fontWeight: 600,
};

export const header1 = {
fontSize: "1.3rem",
lineHeight: "130%",
fontWeight: 700,
};

export const header2 = {
fontSize: "0.9rem",
lineHeight: "130%",
fontWeight: 400,
};
5 changes: 5 additions & 0 deletions packages/wow-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,11 @@
"require": "./dist/MultiGroup.cjs",
"import": "./dist/MultiGroup.js"
},
"./Header": {
"types": "./dist/components/Header/index.d.ts",
"require": "./dist/Header.cjs",
"import": "./dist/Header.js"
},
"./DropDownOption": {
"types": "./dist/components/DropDown/DropDownOption.d.ts",
"require": "./dist/DropDownOption.cjs",
Expand Down
1 change: 1 addition & 0 deletions packages/wow-ui/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export default {
SingleDatePicker: "./src/components/Picker/SingleDatePicker",
TimePicker: "./src/components/Picker/TimePicker",
MultiGroup: "./src/components/MultiGroup",
Header: "./src/components/Header",
DropDownOption: "./src/components/DropDown/DropDownOption",
DropDown: "./src/components/DropDown",
Divider: "./src/components/Divider",
Expand Down
68 changes: 68 additions & 0 deletions packages/wow-ui/src/components/Header/Header.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import type { Meta, StoryObj } from "@storybook/react";

import Header from "@/components/Header";

const meta = {
title: "UI/Header",
component: Header,
tags: ["autodocs"],
parameters: {
componentSubtitle: "헤더 컴포넌트",
a11y: {
config: {
rules: [{ id: "color-contrast", enabled: false }],
},
},
},
argTypes: {
variant: {
control: {
type: "select",
},
options: ["username", "login", "none"],
table: {
type: { summary: "username | login | none" },
},
description:
'헤더 종류를 나타냅니다. variant가 "username"인 경우 오른쪽에 사용자 이름을, "login"인 경우 로그인 버튼을, "none"인 경우 아무것도 표시하지 않습니다.',
},
username: {
control: {
type: "text",
},
table: {
type: { summary: "string" },
},
description:
'variant가 "username"인 경우 표시되는 오른쪽 요소입니다. 사용자가 로그인한 경우 사용자 이름을 표시합니다.',
},
onClick: {
action: "clicked",
control: false,
table: {
type: { summary: "function" },
},
description:
'variant가 "login"인 경우 전달할 수 있습니다. 로그인 버튼 클릭 시 호출되는 함수입니다.',
},
},
} satisfies Meta<typeof Header>;

export default meta;

export const Default: StoryObj<typeof Header> = {
args: {},
};

export const Login: StoryObj<typeof Header> = {
args: {
variant: "login",
},
};

export const Username: StoryObj<typeof Header> = {
args: {
variant: "username",
username: "김홍익",
},
};
115 changes: 115 additions & 0 deletions packages/wow-ui/src/components/Header/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/**
* @description 헤더 컴포넌트입니다.
* 사이트 로고와 로그인 또는 사용자 이름 표시 기능을 포함합니다.
*
* @template T
* @param {"username" | "login" | "none"} [variant] - Header 종류.
* - "username": 사용자 이름을 표시.
* - "login": 로그인 버튼을 표시.
* - "none": 아무것도 표시하지 않음.
* @param {T extends "username" ? string : never} [username] - variant가 "username"인 경우 표시되는 오른쪽 요소. 사용자가 로그인한 경우 사용자 이름을 표시함.
* @param {T extends "login" ? () => void : never} [onClick] - 로그인 버튼 클릭 시 호출되는 함수.
*/

import { css } from "@styled-system/css";
import { Flex } from "@styled-system/jsx";
import { GdscLogo } from "wowds-icons";

import Button from "@/components/Button";

type RightElementType = "username" | "login" | "none";

export interface HeaderProps<T extends RightElementType> {
variant?: T;
username?: T extends "username" ? string : never;
onClick?: T extends "login" ? () => void : never;
}

const Header = ({
variant = "none",
username,
onClick,
}: HeaderProps<RightElementType>) => {
return (
<header aria-label="header" className={headerStyle} role="banner">
<div className={headerContentStyle}>
<section className={leftElementContainerStyle}>
<GdscLogo aria-label="gdsc-logo" role="img" />
<Flex className={logoTextContainerStyle}>
<h1 className={titleStyle}>GDSC</h1>
<h2 className={subTitleStyle}>Hongik Univ.</h2>
</Flex>
</section>
<section>
{variant === "login" && (
<Button size="sm" variant="outline" onClick={onClick}>
로그인/가입하기
</Button>
)}
{variant === "username" && (
<div aria-label={`${username} 님`} className={usernameTextStyle}>
{username}
</div>
)}
</section>
</div>
</header>
);
};

export default Header;

const headerStyle = css({
borderBottomStyle: "solid",
borderBottomWidth: 1,
borderBottomColor: "outline",
height: "54px",
width: "100%",
display: "flex",
alignItems: "center",
xsToLg: {
paddingX: "16px",
height: "66px",
},
});

const headerContentStyle = css({
width: "988px",
display: "flex",
justifyContent: "space-between",
alignItems: "center",
margin: "auto",
});

const leftElementContainerStyle = css({
display: "flex",
gap: "xs",
alignItems: "center",
});

const titleStyle = css({
fontFamily: "Product Sans",
textStyle: "header1",
});

const subTitleStyle = css({
fontFamily: "Product Sans",
color: "primary",
textStyle: "header2",
});

const usernameTextStyle = css({
textStyle: "label1",
});

const logoTextContainerStyle = css({
lg: {
gap: "xs",
alignItems: "center",
},
xsToLg: {
flexDirection: "column",
justifyContent: "flex-start",
alignItems: "space-between",
},
});
612 changes: 611 additions & 1 deletion packages/wow-ui/styled-system/styles.css

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion packages/wow-ui/styled-system/types/prop-type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,9 @@ export interface UtilityValues {
| "body3"
| "label1"
| "label2"
| "label3";
| "label3"
| "header1"
| "header2";
}

type WithColorOpacityModifier<T> = T extends string ? `${T}/${string}` : T;
Expand Down

0 comments on commit b7f51d2

Please sign in to comment.