헤더 Header
헤더는 웹사이트의 상단 헤더 영역을 구성하는 컴포넌트이다. 유틸리티 메뉴, 브랜딩 영역, 네비게이션 메뉴를 내용으로 넣어 유연하게 구성할 수 있다. 네비게이션 자리에는 KrdsMainMenu 등 완성된 메뉴 컴포넌트를 그대로 넣는다.
기본
기본 <header>(banner 랜드마크)에 krdsHeader를 붙이고, 안에 넣은 요소를 KRDS 헤더 구조로 배치합니다. krdsHeaderUtility를 붙인 요소에는 유틸리티 메뉴를, krdsHeaderBranding을 붙인 요소에는 로고와 주요 버튼을 KRDS 헤더 마크업 그대로 넣습니다. PC 메인 메뉴(<krds-main-menu>)는 그냥 넣고, 모바일 드로어(<krds-main-menu variant="mobile">)에는 krdsHeaderMobile 속성을 붙입니다. 유틸리티 메뉴의 드롭다운은 krdsDropdown을 KRDS 드롭다운 마크업에 붙여 엽니다(언어 변경 문서의 드롭다운 참고).
헤더는 화면 상단에 고정(sticky)되고 메인 메뉴를 열면 화면 전체에 배경 딤이 깔리므로 예제를 별도 화면(iframe)에 띄웁니다. 예제는 1024px 폭 화면을 축소해 PC 레이아웃으로 보여 줍니다.
import { Component, signal } from '@angular/core'
import {
KrdsDropdown,
KrdsExternalLink,
KrdsHeader,
KrdsHeaderBranding,
KrdsHeaderUtility,
KrdsMainMenu,
type KrdsMainMenuItem
} from '@krds.ui/angular'
@Component({
selector: 'demo-header-basic',
imports: [KrdsHeader, KrdsHeaderUtility, KrdsHeaderBranding, KrdsMainMenu, KrdsDropdown, KrdsExternalLink],
template: `
<header krdsHeader>
<div krdsHeaderUtility>
<ul class="utility-list">
<li>
<a href="#!" class="krds-btn small text" krdsExternal>메뉴명 <i class="svg-icon ico-go" aria-hidden="true"></i></a>
</li>
<li>
<div krdsDropdown>
<button type="button" class="krds-btn small text drop-btn">
메뉴명 <i class="svg-icon ico-toggle" aria-hidden="true"></i>
</button>
<div class="drop-menu">
<div class="drop-in">
<ul class="drop-list">
<li><a href="#!" class="item-link">메뉴명</a></li>
<li><a href="#!" class="item-link">메뉴명</a></li>
</ul>
</div>
</div>
</div>
</li>
</ul>
</div>
<div krdsHeaderBranding>
<h2 class="logo">
<a href="#!"><span class="sr-only">KRDS - Korea Design System</span></a>
</h2>
<div class="header-actions">
<button type="button" class="btn-navi sch" title="통합검색 레이어">통합검색</button>
<a href="#!" class="btn-navi login">로그인</a>
<button type="button" class="btn-navi join">회원가입</button>
<button
type="button"
class="btn-navi all"
aria-controls="mobile-nav"
[attr.aria-expanded]="mobileOpen()"
(click)="mobileOpen.set(true)"
>
전체메뉴
</button>
</div>
</div>
<krds-main-menu [items]="menuItems" />
<krds-main-menu krdsHeaderMobile variant="mobile" [items]="menuItems" [(open)]="mobileOpen" />
</header>
`
})
export default class HeaderBasic {
readonly menuItems: KrdsMainMenuItem[] = [
{
text: '1Depth',
subItems: [
{
text: '2Depth-menu',
items: [
{ text: '3Depth-menu', href: '#!' },
{ text: '3Depth-menu', href: '#!' }
]
},
{
text: '2Depth-menu',
items: [
{ text: '3Depth-menu', href: '#!' },
{ text: '3Depth-menu', href: '#!' }
]
}
]
},
{
text: '1Depth',
subItems: [
{
text: '2Depth-menu',
items: [
{ text: '3Depth-menu', href: '#!' },
{ text: '3Depth-menu', href: '#!' }
]
}
]
},
{ text: '링크(anchor)', href: '#!' }
]
readonly mobileOpen = signal(false)
}모바일
1024px 미만 화면에서는 유틸리티 메뉴와 PC 메인 메뉴가 숨겨지고 전체메뉴 버튼이 표시됩니다. 전체메뉴 버튼의 aria-controls를 모바일 드로어 id(KrdsMainMenu의 mobileId, 기본값 mobile-nav)에 연결하고 [(open)]으로 드로어를 엽니다. 드로어는 열리면 초점을 안으로 옮기고, 닫히면 연 버튼으로 돌려줍니다. 아래는 같은 예제를 문서 폭(1024px 미만) 그대로 띄운 것으로, 전체메뉴 버튼으로 드로어를 확인할 수 있습니다.
KrdsHeader
선택자 header[krdsHeader]
Inputs
| 이름 | 타입 | 기본값 | 설명 |
|---|---|---|---|
id | string | 'krds-header' | id (KRDS CSS 기준 krds-header) |
KrdsHeaderUtility
선택자 [krdsHeaderUtility]
Inputs
없음
KrdsHeaderBranding
선택자 [krdsHeaderBranding]
Inputs
없음
KrdsMainMenu
선택자 krds-main-menu
Inputs
| 이름 | 타입 | 기본값 | 설명 |
|---|---|---|---|
items | KrdsMainMenuItem[] | [] | 메뉴 항목 |
variant | 'pc' | 'mobile' | 'pc' | 렌더링 방식 |
label | string | '메인 메뉴' | 메뉴 이름 |
[(open)] | boolean | false | 모바일 드로어 열림 |
mobileId | string | 'mobile-nav' | 모바일 드로어 id (바깥 열기 버튼의 aria-controls 대상) |
backdrop | boolean | true | PC 패널이 열리면 배경을 어둡게 |
closeLabel | string | '전체메뉴 닫기' | 모바일 닫기 버튼 문구 |
Outputs
| 이름 | 값 | 설명 |
|---|---|---|
menuToggle | KrdsMainMenuToggle | PC 패널을 열거나 닫았을 때 |
itemClick | KrdsMainMenuClick | 메뉴 항목을 클릭했을 때 |
타입
/** 1단계 항목 (subItems가 있으면 2단계 목록이 있는 패널, items만 있으면 링크만 나열하는 single-list 패널, 둘 다 없으면 링크) */
export interface KrdsMainMenuItem {
text: string
href?: string
external?: boolean
subItems?: KrdsMainMenuSubItem[]
items?: KrdsMainMenuLinkItem[]
/** single-list 패널 제목 */
title?: string
banner?: boolean
layout?: KrdsMainMenuLayout
selected?: boolean
}
/** PC 패널 열림 이벤트 */
export interface KrdsMainMenuToggle {
index: number
expanded: boolean
}
/** 메뉴 항목 클릭 이벤트 (라우터로 이동하려면 event.preventDefault()) */
export interface KrdsMainMenuClick {
item: KrdsMainMenuItem | KrdsMainMenuSubItem | KrdsMainMenuLinkItem | KrdsMainMenuDepth4Item
event: MouseEvent
}
/** 2단계 항목 (items가 있으면 서브 패널을 여는 버튼, 없으면 바로가기 링크) */
export interface KrdsMainMenuSubItem {
text: string
href?: string
external?: boolean
/** 서브 패널 제목 (기본: text) */
title?: string
/** 서브 패널 제목 옆 바로가기 링크 (PC) */
titleLink?: { text?: string; href: string }
items?: KrdsMainMenuLinkItem[]
/** 배너 영역 표시 (krdsMainMenuBanner 템플릿, PC) */
banner?: boolean
layout?: KrdsMainMenuLayout
/** 모바일 3단계 처음 펼침 */
expanded?: boolean
selected?: boolean
}
/** 링크 항목 (PC 서브 패널의 마지막 단계, 모바일 3단계) */
export interface KrdsMainMenuLinkItem {
text: string
/** 링크 주소 (없으면 button) */
href?: string
external?: boolean
/** 메뉴 설명 (PC type-description) */
description?: string
selected?: boolean
/** 모바일 4단계 패널 제목 (기본: text) */
panelTitle?: string
/** 모바일 4단계 항목 */
items?: KrdsMainMenuDepth4Item[]
}
/** 모바일 4단계 항목 */
export interface KrdsMainMenuDepth4Item {
text: string
href?: string
/** 새 창 열림 */
external?: boolean
/** 현재 페이지 */
selected?: boolean
}