# Page Header (Pattern) 현재 HM 구현의 기준 문서. 공통 원칙은 [프로젝트 지침](../guidelines/프로젝트-지침.md), [Button 규칙](../components/button.md), [단일 Navigation 정책](../guidelines/navigation-single-mode.md)을 따른다. ```text 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](../../src/patterns/page-header.stories.tsx) (`patterns-layout-page-header--all`) | | Dashboard 사용 예 | [Patterns/Layout/Dashboard → Dashboard](../../src/patterns/dashboard-layout.stories.tsx). 기존 대표 Story와 Dashboard 내부 조합 유지 | | 분리 이유 | 모든 화면이 Breadcrumb + h1 + 액션을 반복하고, 하단 20px이 Layout contract | ## 2. 구성 / API | export | 역할 | |---|---| | `PageHeader` | 행(flex, space-between, 하단 정렬, 줄바꿈) | | `PageHeaderContent` | 시작 쪽 세로 묶음 | | `PageHeaderTitle` | `h1`(화면의 유일한 h1) | | `PageHeaderDescription` | 설명/메타 `p` | | `PageHeaderActions` | 끝 쪽 액션 행(Button, Dropdown Menu) | ```tsx import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, PageHeader, PageHeaderActions, PageHeaderContent, PageHeaderDescription, PageHeaderTitle, } from "@hm-design/ui" 홈 프로젝트 업무 현황 업무 현황 프로젝트별 업무 진행 상황을 확인하고 조회합니다. ``` Breadcrumb와 액션 API는 정의하지 않는다(composition). 구분선은 없다(ui-viz에 없음). 대표 예제는 지원되는 `primary × brand`, `size="default"`(Medium 34px) Action 1개를 사용한다. 화면당 Brand는 최대 1개이며 `appearance`를 명시한다. 복수 Action의 PageHeader 전용 세트 규칙은 아직 확정하지 않았으므로 기존 Dashboard fixture를 공통 세트 규칙으로 일반화하지 않는다. 보조 Action이 필요하면 [Button의 사용 위치·세트 규칙과 허용 조합](../components/button.md)을 확인하고, 불명확한 조합은 사용자 결정 후 적용한다. 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 소스](../../src/patterns/page-header.stories.tsx): 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 ```