feat(component): 섹션 타이틀 컴포넌트를 추가한다

This commit is contained in:
Yu Sung
2026-05-19 21:26:47 +09:00
parent 942c581eaf
commit ca8da51991
5 changed files with 332 additions and 0 deletions

View File

@@ -0,0 +1,129 @@
# 20260519 섹션 타이틀 컴포넌트 계획
> 구현 시 문서 범위를 벗어나지 않는다. 신규 UI 컴포넌트 작업이므로 구현 단계에서는 시각/UI 전용 실행 경로를 사용한다.
**Goal:** Figma 노드 `20:3614`의 42pt 섹션 타이틀을 V2 SwiftUI 재사용 컴포넌트로 구현한다.
**Architecture:** 신규 `SectionTitle` View 하나를 `SodaLive/Sources/V2/Component`에 추가한다. 기존 `TitleBar` 계열은 화면 상단 네비게이션 바 책임을 유지하고, 섹션 헤더는 별도 컴포넌트로 분리한다.
**Tech Stack:** SwiftUI, existing `SodaSpacing`, existing `SodaTypography`, existing asset catalog
---
## 기준 문서
- PRD: `docs/prd/20260519_섹션타이틀컴포넌트_PRD.md`
- 검증 가이드: `docs/agent-guides/build-test-verification.md`
- 코드 스타일: `docs/agent-guides/code-style.md`
## 구현 대상 파일 후보
### 생성
- `SodaLive/Sources/V2/Component/SectionTitle.swift`: Figma 섹션 타이틀의 레이아웃, 스타일, 버튼 동작, Preview 담당
### 참조
- `SodaLive/Sources/V2/Component/TitleBar.swift`: 기존 V2 컴포넌트 스타일 참고
- `SodaLive/Sources/Extensions/FontModifier.swift`: `.appFont(.heading3)`의 20pt bold 매핑 확인
- `SodaLive/Sources/UI/Theme/Spacing.swift`: `SodaSpacing.s20` 확인
- `SodaLive/Resources/Assets.xcassets/v2/ic_chevron_right.imageset/Contents.json`: 우측 chevron 에셋 확인
### 수정하지 않음
- `SodaLive/Sources/V2/Component/TitleBar.swift`: 기존 상단 바 동작 유지
- `SodaLive/Sources/V2/Component/DefaultTitleBar.swift`: 기존 상단 바 동작 유지
- `SodaLive/Sources/V2/Component/HomeTitleBar.swift`: 기존 상단 바 동작 유지
- `SodaLive/Resources/Assets.xcassets/**`: 신규 에셋 추가 없음
## 구현 체크리스트
### Task 1: 에셋 확인
**Files:** `SodaLive/Resources/Assets.xcassets/v2/ic_chevron_right.imageset/Contents.json`
- [x] `ic_chevron_right.imageset` 아래 `Contents.json``ic_chevron_right.png`가 존재하는지 확인한다.
- [x] `Contents.json``images` 배열이 있고 `ic_chevron_right.png`가 등록되어 있는지 확인한다.
- [x] QA: `Image("ic_chevron_right")`로 참조 가능한 asset catalog 이름인지 확인한다.
### Task 2: SectionTitle 작성
**Files:** `SodaLive/Sources/V2/Component/SectionTitle.swift`
- [x] `struct SectionTitle: View`를 생성한다.
- [x] `title: String`, `action: (() -> Void)? = nil` 초기화 API를 제공한다.
- [x] `HStack(alignment: .center, spacing: 0)`에 제목, `Spacer(minLength: 0)`, 조건부 chevron을 배치한다.
- [x] 최상위 content에 `.padding(.horizontal, SodaSpacing.s20)`, `.frame(maxWidth: .infinity)`, `.frame(height: 42, alignment: .center)`를 적용한다.
- [x] 제목은 `.appFont(.heading3)`, `.foregroundColor(.white)`, `.lineLimit(1)`, `.truncationMode(.tail)`을 적용한다.
- [x] `action`이 있을 때 chevron은 `Image("ic_chevron_right")`를 사용하고 24x24로 표시한다.
- [x] chevron은 plain `Button`으로 감싸고 `.accessibilityLabel(title)`을 적용한다.
- [x] `action`이 없으면 chevron 없이 정적 content만 렌더링한다.
- [x] 제목 영역은 탭해도 `action`이 실행되지 않도록 한다.
### Task 3: Preview 작성
**Files:** `SodaLive/Sources/V2/Component/SectionTitle.swift`
- [x] action이 없는 chevron 미표시 케이스 Preview를 추가한다.
- [x] action이 있는 chevron 표시 케이스 Preview를 추가한다.
- [x] 긴 제목 말줄임 케이스 Preview를 추가한다.
- [x] QA: Preview 배경은 확인용으로만 지정하고 컴포넌트 본문에는 배경을 넣지 않는다.
### Task 4: 정적 진단
**Files:** `SodaLive/Sources/V2/Component/SectionTitle.swift`
- [x] `lsp_diagnostics`로 신규 Swift 파일의 정적 진단을 확인한다.
- [x] SourceKit 단일 파일 문맥 문제로 프로젝트 심볼 미해결이 발생하면 같은 변경을 `xcodebuild`로 검증한다.
- [x] 컴포넌트 구현에서 발생한 실제 Swift 오류가 있으면 `SectionTitle.swift`만 수정한다.
### Task 5: 빌드 검증
**Files:** `SodaLive.xcworkspace`, `SodaLive/Sources/V2/Component/SectionTitle.swift`
- [x] `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build`를 실행한다.
- [x] 가능한 경우 `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build`도 실행한다.
- [x] 환경 문제로 빌드가 실패하면 첫 번째 유효 오류 라인을 검증 기록에 남긴다.
- [x] 코드 문제로 빌드가 실패하면 `SectionTitle.swift`만 수정한 뒤 같은 명령을 재실행한다.
### Task 6: PRD 성공 기준 대조
**Files:** `docs/prd/20260519_섹션타이틀컴포넌트_PRD.md`, `SodaLive/Sources/V2/Component/SectionTitle.swift`
- [x] 높이 42, full width, 좌우 20pt 여백이 구현됐는지 확인한다.
- [x] 제목이 `.appFont(.heading3)`와 흰색으로 표시되는지 확인한다.
- [x] 긴 제목이 한 줄 말줄임 처리되는지 확인한다.
- [x] `action` 유무에 따른 chevron 표시 분기가 구현됐는지 확인한다.
- [x] `action`이 chevron 버튼에만 연결되고 제목 영역에는 연결되지 않았는지 확인한다.
- [x] 기존 `TitleBar`, `DefaultTitleBar`, `HomeTitleBar`를 수정하지 않았는지 확인한다.
## 구현 시 주의사항
- 기존 `TitleBar`, `DefaultTitleBar`, `HomeTitleBar`를 변경하지 않는다.
- 신규 디자인 토큰을 추가하지 않는다.
- `Image(systemName:)`을 사용하지 않는다.
- 화면 적용, 라우팅, API 연동은 별도 요청 전까지 하지 않는다.
- 파일 생성 위치는 `SodaLive/Sources/V2/Component`로 고정한다.
## 검증 기록
- 2026-05-19 문서 작성 전 Figma 노드 `20:3614`의 screenshot/design context를 확인해 높이 42, 좌우 20, 20pt bold title, 우측 24pt chevron 구조를 확인했다.
- 2026-05-19 문서 작성 전 `SodaLive/Sources/V2/Component/TitleBar.swift`, `DefaultTitleBar.swift`, `HomeTitleBar.swift`를 확인해 기존 V2 상단 바 컴포넌트와 책임을 분리해야 함을 확인했다.
- 2026-05-19 문서 작성 전 `SodaLive/Sources/Extensions/FontModifier.swift`를 확인해 `.appFont(.heading3)`가 20pt bold임을 확인했다.
- 2026-05-19 문서 작성 전 `SodaLive/Sources/UI/Theme/Spacing.swift`를 확인해 `SodaSpacing.s20` 사용 가능성을 확인했다.
- 2026-05-19 문서 작성 전 `SodaLive/Resources/Assets.xcassets/v2/ic_chevron_right.imageset/Contents.json`을 확인해 `ic_chevron_right` 에셋 존재를 확인했다.
- 2026-05-19 문서 위치 보정: `AGENTS.md``docs/agent-guides/documentation-policy.md` 기준에 맞춰 PRD는 `docs/prd/20260519_섹션타이틀컴포넌트_PRD.md`, 계획/TASK는 `docs/plan-task/20260519_섹션타이틀컴포넌트.md`로 정리했다.
- 2026-05-19 구현: `SodaLive/Sources/V2/Component/SectionTitle.swift`를 추가하고, `SodaLive.xcodeproj/project.pbxproj``SectionTitle.swift``SodaLive`, `SodaLive-dev` 두 앱 타깃 Sources로 등록했다.
- 2026-05-19 수동 QA: `rg``SectionTitle.swift``action: (() -> Void)? = nil`, `Image("ic_chevron_right")`, 24x24 chevron, 42pt height, 프로젝트 Sources 등록 2건을 확인했다.
- 2026-05-19 에셋 검증: `plutil -p 'SodaLive/Resources/Assets.xcassets/v2/ic_chevron_right.imageset/Contents.json'` 결과 `ic_chevron_right.png``images` 배열에 등록되어 있음을 확인했다.
- 2026-05-19 프로젝트 검증: `plutil -lint SodaLive.xcodeproj/project.pbxproj` 실행 결과 `OK`.
- 2026-05-19 LSP 진단: `SectionTitle.swift` 단일 파일 진단에서 `SodaSpacing`, `.appFont`, `.heading3`, `.white`, `.tail` 프로젝트 문맥 미해결 오류가 보고됐다. 동일 오류는 기존 `TitleBar.swift`에서도 재현되어 SourceKit 단일 파일 문맥 한계로 기록하고, 실제 컴파일 유효성은 아래 빌드로 확인했다.
- 2026-05-19 빌드 검증: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build` 실행 결과 `** BUILD SUCCEEDED **`.
- 2026-05-19 빌드 검증: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build` 실행 결과 `** BUILD SUCCEEDED **`. Crashlytics dSYM 및 일부 dependency scan 경고가 있었으나 빌드는 성공했다.
- 2026-05-19 테스트 액션 확인: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" test` 실행 결과 `Scheme SodaLive-dev is not currently configured for the test action.`으로 테스트 타깃 미구성 상태를 확인했다.
- 2026-05-19 동작 수정: 별도 chevron 표시 API를 제거하고, `action`이 있을 때만 `ic_chevron_right` chevron 버튼을 표시하도록 변경했다. `action`은 전체 행이 아니라 chevron 버튼에만 연결해 제목 터치로는 실행되지 않게 했다.
- 2026-05-19 동작 수정 후 수동 QA: `rg``Text(title)``Button(action: action)`이 분리되어 있고, `Image("ic_chevron_right")`, 24x24 chevron, 42pt height, action 없는 Preview/action 있는 Preview가 존재함을 확인했다.
- 2026-05-19 동작 수정 후 LSP 진단: `SectionTitle.swift` 단일 파일 진단에서 기존과 같은 `SodaSpacing`, `.appFont`, `.heading3`, `.white`, `.tail` 프로젝트 문맥 미해결 오류가 보고됐다. 실제 컴파일 유효성은 아래 빌드로 확인했다.
- 2026-05-19 동작 수정 후 빌드 검증: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build` 실행 결과 `** BUILD SUCCEEDED **`.
- 2026-05-19 동작 수정 후 빌드 검증: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build` 실행 결과 `** BUILD SUCCEEDED **`. Crashlytics dSYM 및 일부 dependency scan 경고가 있었으나 빌드는 성공했다.
- 2026-05-19 동작 수정 후 테스트 액션 확인: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" test` 실행 결과 `Scheme SodaLive-dev is not currently configured for the test action.`으로 테스트 타깃 미구성 상태를 재확인했다.

View File

@@ -0,0 +1,119 @@
# PRD: 섹션 타이틀 컴포넌트
## 1. Overview
Figma 노드 `20:3614`의 42pt 섹션 타이틀을 SwiftUI 재사용 컴포넌트로 정의한다. 신규 UI 컴포넌트 위치 규칙에 따라 구현 대상은 `SodaLive/Sources/V2/Component/**` 아래에 둔다.
---
## 2. Background
Figma 노드 `20:3614`는 402x42 크기의 섹션 타이틀 컴포넌트다. 좌측에는 `Pretendard Variable Bold 20pt` 텍스트가 있고, 우측에는 24x24 chevron-right 아이콘이 조건부로 표시된다.
최근 코드에는 다음 기반 요소가 이미 존재한다.
- `SodaLive/Sources/V2/Component/TitleBar.swift`: V2 상단 바 컴포넌트 스타일 참고 가능
- `SodaLive/Sources/Extensions/FontModifier.swift`: `SodaTypography.heading3``.appFont(_:)` 제공
- `SodaLive/Sources/UI/Theme/Spacing.swift`: `SodaSpacing.s20` 제공
- `SodaLive/Resources/Assets.xcassets/v2/ic_chevron_right.imageset`: 우측 chevron 에셋 존재
---
## 3. Goals
- Figma 시안과 동일한 높이, 여백, 타이포그래피를 SwiftUI로 구현한다.
- 기존 V2 컴포넌트 관례와 디자인 토큰을 사용한다.
- 제목 텍스트와 우측 chevron 탭 동작을 호출부에서 제어할 수 있게 한다.
- 네비게이션 상단 바인 `TitleBar`와 책임을 분리한다.
---
## 4. Non-Goals
- 화면 단위 라우팅이나 API 연동은 포함하지 않는다.
- 신규 디자인 토큰을 추가하지 않는다.
- Figma의 React/Tailwind 생성 코드를 그대로 이식하지 않는다.
- 기존 `TitleBar`, `DefaultTitleBar`, `HomeTitleBar`의 동작을 변경하지 않는다.
---
## 5. Core Requirements
### 5.1 컴포넌트 API
- 컴포넌트 이름은 `SectionTitle`로 둔다.
- `title: String`을 호출부에서 전달한다.
- `action: (() -> Void)?`는 기본값 `nil`을 사용한다.
- `action`이 있으면 우측 chevron만 `Button`으로 렌더링한다.
- `action`이 없으면 chevron을 표시하지 않고 정적 `HStack`을 표시한다.
### 5.2 레이아웃
- Width: full
- Height: `42`
- Horizontal padding: `SodaSpacing.s20`
- Alignment: 세로 가운데 정렬
- 좌측 제목, `Spacer(minLength: 0)`, 우측 chevron의 `HStack` 구조를 사용한다.
- 우측 chevron은 `action != nil`일 때만 24x24 크기로 표시한다.
### 5.3 스타일
- 제목은 `Text(title).appFont(.heading3)`를 사용한다.
- 제목 색상은 `Color.white`를 사용한다.
- 제목은 한 줄로 제한하고 말줄임 처리한다.
- 컴포넌트 본문에는 배경색을 지정하지 않는다.
### 5.4 아이콘 및 접근성
- 우측 chevron은 기존 에셋 `ic_chevron_right`를 사용한다.
- SwiftUI `Image(systemName: "chevron.right")`는 앱 에셋 스타일과 다를 수 있으므로 사용하지 않는다.
- `action`이 있을 때 chevron 버튼의 접근성 라벨은 `title`을 사용한다.
- 제목 영역은 탭해도 `action`을 실행하지 않는다.
---
## 6. Recommended Approach
전용 `SectionTitle` 컴포넌트를 신규 추가한다. 기존 `TitleBar`를 확장하지 않는 이유는 `TitleBar`가 화면 상단 네비게이션 바 책임을 갖고 있고 높이도 60pt라, Figma의 42pt 섹션 헤더와 의미 및 치수가 다르기 때문이다.
단순 호출부 인라인 구현도 가능하지만 재사용성과 디자인 일관성이 떨어진다. 따라서 `SodaLive/Sources/V2/Component/SectionTitle.swift`에 작고 독립적인 View로 구현한다.
---
## 7. Technical Constraints
- SwiftUI 기반으로 작성한다.
- 신규 파일은 구현 시 `SodaLive/Sources/V2/Component/**` 아래에 둔다.
- 색상과 spacing은 기존 토큰을 우선 사용한다.
- 폰트는 기존 `.appFont(.heading3)` 사용을 우선한다.
- 프로젝트 설정 변경은 필요한 경우에만 수행한다.
---
## 8. Success Criteria
- 문서 기준 구현 후 `SectionTitle`은 높이 42, full width, 좌우 20pt 여백을 갖는다.
- 제목은 20pt bold에 해당하는 `.appFont(.heading3)`와 흰색으로 표시된다.
- 긴 제목은 한 줄 말줄임 처리된다.
- `action`이 있으면 우측 24x24 chevron이 표시되고, 없으면 표시되지 않는다.
- `action`은 chevron을 탭했을 때만 실행되고, 제목 영역을 탭했을 때는 실행되지 않는다.
- 기존 `TitleBar`, `DefaultTitleBar`, `HomeTitleBar` 동작은 바뀌지 않는다.
---
## 9. Decisions
- 파일 생성 위치는 `SodaLive/Sources/V2/Component/SectionTitle.swift`로 결정한다.
- 우측 chevron은 `action`이 있을 때만 `ic_chevron_right`를 사용한다.
- 신규 디자인 토큰은 추가하지 않는다.
- 이번 PRD는 Figma 노드 `20:3614` 단일 컴포넌트만 다룬다.
---
## 10. Verification Notes
- Figma 노드 `20:3614`의 스크린샷과 생성 코드에서 높이 42, 좌우 20, 20pt bold title, 우측 24pt chevron 구조를 확인했다.
- `SodaLive/Sources/V2/Component/TitleBar.swift`를 확인해 V2 컴포넌트의 SwiftUI 스타일을 확인했다.
- `SodaLive/Sources/Extensions/FontModifier.swift`를 확인해 `.appFont(.heading3)`가 20pt bold임을 확인했다.
- `SodaLive/Sources/UI/Theme/Spacing.swift`를 확인해 `SodaSpacing.s20` 사용 가능성을 확인했다.
- `SodaLive/Resources/Assets.xcassets/v2/ic_chevron_right.imageset/Contents.json`을 확인해 `ic_chevron_right` 에셋 존재를 확인했다.