7.4 KiB
Page Header (Pattern)
현재 HM 구현의 기준 문서. 공통 원칙은 프로젝트 지침, Button 규칙, 단일 Navigation 정책을 따른다.
Layout visual reference: 외부 ui_viz Reference (ZIP 미포함) (dashboard-composition.md §8 Page Heading)
Implementation: HM Breadcrumb / Button / Dropdown Menu composed as children
1. 상태
| 항목 | 내용 |
|---|---|
| 구현 상태 | 구현 완료 (2026-10-03) |
| 대표 Story | Patterns/Layout/Page Header → Page Header (patterns-layout-page-header--all) |
| Dashboard 사용 예 | Patterns/Layout/Dashboard → Dashboard. 기존 대표 Story와 Dashboard 내부 조합 유지 |
| 분리 이유 | 모든 화면이 Breadcrumb + h1 + 액션을 반복하고, 하단 20px이 Layout contract |
2. 구성 / API
| export | 역할 |
|---|---|
PageHeader |
행(flex, space-between, 하단 정렬, 줄바꿈) |
PageHeaderContent |
시작 쪽 세로 묶음 |
PageHeaderTitle |
h1(화면의 유일한 h1) |
PageHeaderDescription |
설명/메타 p |
PageHeaderActions |
끝 쪽 액션 행(Button, Dropdown Menu) |
import {
Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList,
BreadcrumbPage, BreadcrumbSeparator, Button,
PageHeader, PageHeaderActions, PageHeaderContent,
PageHeaderDescription, PageHeaderTitle,
} from "@hm-design/ui"
<PageHeader>
<PageHeaderContent>
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem><BreadcrumbLink href="#home">홈</BreadcrumbLink></BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem><BreadcrumbLink href="#projects">프로젝트</BreadcrumbLink></BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem><BreadcrumbPage>업무 현황</BreadcrumbPage></BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
<PageHeaderTitle>업무 현황</PageHeaderTitle>
<PageHeaderDescription>프로젝트별 업무 진행 상황을 확인하고 조회합니다.</PageHeaderDescription>
</PageHeaderContent>
<PageHeaderActions>
<Button type="button" variant="primary" appearance="brand" size="default">신규 등록</Button>
</PageHeaderActions>
</PageHeader>
Breadcrumb와 액션 API는 정의하지 않는다(composition). 구분선은 없다(ui-viz에 없음).
대표 예제는 지원되는 primary × brand, size="default"(Medium 34px) Action 1개를 사용한다. 화면당 Brand는 최대 1개이며 appearance를 명시한다. 복수 Action의 PageHeader 전용 세트 규칙은 아직 확정하지 않았으므로 기존 Dashboard fixture를 공통 세트 규칙으로 일반화하지 않는다. 보조 Action이 필요하면 Button의 사용 위치·세트 규칙과 허용 조합을 확인하고, 불명확한 조합은 사용자 결정 후 적용한다.
Story의 Breadcrumb hash 링크와 등록 버튼은 조합 예제다. 실제 화면은 해당 Runtime의 라우팅과 등록 처리 callback을 연결한다. React 소비 화면은 entry에서 @hm-design/ui/theme.css를 로드한다. Storybook은 기존 전역 Theme 연결을 재사용한다.
3. Token (packages/ui/src/theme/page-header.css)
| Token | 값 | ui-viz |
|---|---|---|
--hm-page-header-gap |
24px | MATCHED (gap 24) |
--hm-page-header-margin-bottom |
20px | MATCHED (D-043, 첫 카드까지 20) |
--hm-page-header-breadcrumb-gap |
10px | MATCHED |
| title | 28/36/700, 아래→설명 8px | MATCHED (h2 → h1은 INTENTIONAL_CHANGE) |
| description | 14/20, --hm-sem-fg-secondary |
MATCHED (색은 ui-viz 임시값 대신 Semantic) |
| actions gap | 8px | 정의 없음(Button 간격) |
Breadcrumb는 HM Breadcrumb 그대로(14px, 링크). ui-viz는 12px 정적 텍스트였다(INTENTIONAL_CHANGE).
4. Responsive / Accessibility
PageHeaderContent는 flex: 1 1 320px; min-width: 0, 액션은 줄바꿈 후 오른쪽 정렬(390px에서 제목 아래 줄). 긴 제목은 overflow-wrap: anywhere. 화면당 h1은 하나만 둔다. wrapper에 role을 두지 않는다.
PageHeader는 콘텐츠의 제목 영역이며 Navigation Mode를 정의하지 않는다. 독립 대표 Story는 Navigation을 추가하지 않은 조합 예제다. 실제 페이지는 GNB | LNB | DASHBOARD 중 하나만 선택하고 반응형에서도 유지한다. Dashboard에서는 Dashboard 내부 Header/Menu/Sidebar와 합성하며 외부 GNB/LNB를 함께 넣지 않는다.
Dashboard Compact 최소 폭 960px(Sidebar 포함 1232px)과 내부 가로 스크롤은 Dashboard Layout 계약이다. PageHeader 단독 사용처에 이 최소 폭을 자동 적용하지 않는다. PageHeader 자체에는 고정 최소 폭이나 별도 breakpoint가 없으며 기존 flex wrapping과 Theme 규격을 유지한다. 외부 콘텐츠 padding은 소비 Layout이 소유한다.
5. 검증 / 관련 파일
현재 대표 Reference
- 독립 대표 Story 소스: Breadcrumb + Title + Description + Actions. 운영 조합에 별도 Story CSS나 Dashboard 최소 폭을 추가하지 않는다.
- Storybook 경로:
Patterns/Layout/Page Header → Page Header, ID:patterns-layout-page-header--all. - 기존 Dashboard 대표 Story는 Dashboard 전체 Layout의 Reference로 유지한다. Verification Story는 운영 Reference로 사용하지 않는다.
2026-10-08 독립 대표 Story 검증
- 기존 6024 Storybook에서 독립 메뉴와 대표 Story 렌더링 확인. 1440×900 / 390×844에서 네 구성 요소가 표시되고 문서·body의 가로 넘침 없음. 모바일 Action은 아래 줄 오른쪽으로 배치된다.
- Computed style: Title 28/36/700, Breadcrumb 14/20, Description 14/20와 Secondary 전경, PageHeader gap 24px·하단 margin 20px·Actions gap 8px 유지. 기존 Noto Sans KR와 Theme Semantic 연결 확인.
primary × brand,size="default"버튼 1개·높이 34px 확인. Breadcrumb 링크 → Action의 Tab 순서와 focus-visible 링 유지. 콘텐츠의 보이는h1은 1개다.- 기존 Dashboard 대표 Story 정상 렌더. Header 48px·Variant C Typography·상태 필터 유지, 이슈 5건 조회 및 전체 47건 복원 확인. 390px에서 Dashboard 최소 폭 960px과 내부 가로 스크롤 유지.
- PageHeader / Dashboard Console 오류·경고 없음. Storybook 관리자에는 기존
PopoverProvider ariaLabel의 Storybook 11 예정 변경 경고 1건이 있다. - 새 Story만 대상으로 한 최소 TypeScript 검사와 변경 파일 diff check 통과. 앱 범위 검사는 다른 작업의 Controlled Props와 패키지 선언 불일치 오류 6건으로 실패했으며 해당 파일은 수정하지 않았다. 전체 Component 회귀·build는 이번 범위에서 수행하지 않았다.
과거 검증 기록 (기존 문서)
당시 Dashboard Layout Story(1280, 390, 긴 제목)에서 page-header 상단이 Main padding 34 아래, 하단 20px 뒤에 첫 콘텐츠인 것을 확인했다. 이는 당시 Dashboard 조합의 검증 기록이며, 현재 Dashboard 최소 폭·내부 가로 스크롤 정책이나 모든 PageHeader 소비 화면의 padding 규격을 대신하지 않는다.
packages/ui/src/patterns/page-header/{page-header.tsx,index.ts}
packages/ui/src/theme/page-header.css
src/patterns/page-header.stories.tsx
src/patterns/dashboard-layout.stories.tsx