[Feat] [토닥이] Todak Header 컴포넌트 추가 (#47) - #46
Conversation
- Figma 기준 Todak Header 상세 명세와 참조 이미지를 추가했습니다. - DesignSystem Figma 명세 인덱스에 Todak Header 링크와 썸네일을 연결했습니다.
- Todak Header에서 사용하는 chatAdd, deleteLine, notes 아이콘 에셋을 추가했습니다. - coolGray975 컬러를 DesignSystem 색상 API와 카탈로그에 연결했습니다. - DSIconAsset 매핑 테스트에 신규 아이콘을 반영했습니다.
- AI 채팅 화면 전용 DSTodakHeader를 추가하고 무료 채팅 잔여 횟수를 표시하도록 구현했습니다. - 우측 액션은 rightItems 배열로 주입받고 버튼 크기와 색상, pressed 스타일은 컴포넌트가 관리하도록 구성했습니다. - DesignSystemExample Playground와 Specification 매핑 테스트를 추가했습니다.
|
Warning Review limit reached
Next review available in: 16 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
WalkthroughTodak Header SwiftUI 컴포넌트와 공개 스펙, 관련 아이콘·색상 자산, DesignSystemExample 플레이그라운드, Figma 명세 및 테스트가 추가되었습니다. ChangesTodak Header 컴포넌트
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Playground as TodakHeaderPlaygroundView
participant Header as DSTodakHeader
participant Action as DSHeaderActionItem.action
Playground->>Header: remainingFreeChatCount와 rightItems 전달
Header-->>Playground: 헤더 타이틀 및 버튼 렌더링
Playground->>Header: 우측 버튼 탭
Header->>Action: 주입된 action 호출
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 2📝 Generate docstrings 💡
⚔️ Resolve merge conflicts 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
- Markdown에서 공백이 포함된 이미지 경로를 인코딩해 렌더링 안정성을 확보합니다. - 리뷰에 불필요한 Figma API 작업 과정 설명을 제거합니다.
MoonGoon72
left a comment
There was a problem hiding this comment.
AI 1차 셀프 코드 리뷰 및 주요 설계 결정 설명입니다. Quick Preflight Review에서 확인한 책임 경계와 수동 QA 지점을 중심으로 남겼습니다.
| Spacer() | ||
|
|
||
| HStack(spacing: spec.rightIconGap) { | ||
| ForEach(rightItems, id: \.identifier) { item in |
There was a problem hiding this comment.
우측 액션은 디자인상 chatAdd, notes 두 개가 기본 구성이지만 컴포넌트가 개수나 종류를 강제하지 않도록 배열로 열어두었습니다. 호출부가 아이콘과 action을 결정하고, 헤더는 20x20 크기·12pt 간격·tint·pressed 스타일만 일관되게 소유합니다. identifier는 ForEach의 안정적인 identity이므로 한 배열 안에서 중복되지 않아야 합니다.
| .padding(.horizontal, spec.horizontalPadding) | ||
| } | ||
| .frame(maxWidth: .infinity) | ||
| .frame(height: spec.contentHeight) |
There was a problem hiding this comment.
Figma의 100pt 프레임에는 상태 표시 영역 52pt가 포함되어 있어, 이 View는 실제 헤더 콘텐츠 48pt만 제공합니다. safe area까지 여기서 소유하면 화면 컨테이너와 책임이 겹치므로 노치/Dynamic Island 아래 배치는 사용하는 화면의 SwiftUI safe-area 레이아웃에 맡겼습니다.
| ( | ||
| Text("오늘 무료 채팅 ") | ||
| .font(.ds.font(spec.subtitleFontStyle)) | ||
| .foregroundColor(spec.subtitleTextAsset.swiftUIColor) | ||
| + Text("\(remainingFreeChatCount)") | ||
| .font(.ds.font(spec.remainingCountFontStyle)) | ||
| .foregroundColor(spec.remainingCountTextAsset.swiftUIColor) | ||
| + Text("/\(spec.freeChatLimit)") | ||
| .font(.ds.font(spec.remainingCountFontStyle)) | ||
| .foregroundColor(spec.subtitleTextAsset.swiftUIColor) |
There was a problem hiding this comment.
여러 Text를 결합해 한 문구의 레이아웃은 유지하면서 구간별 명세를 적용했습니다. prefix는 body3Regular/gray500, 잔여 횟수만 body3Medium/gray800, /3은 body3Medium/gray500입니다. remainingFreeChatCount는 Feature가 소유하는 서버 상태이므로 DesignSystem에서는 clamp하지 않고 전달값을 그대로 표시합니다.
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@Projects/Core/DesignSystem/Docs/Components/Todak_Header.md`:
- Line 36: 문서의 해당 Markdown 코드 스팬에서 백틱 내부의 선행·후행 공백을 제거하여 MD038 경고를 해결하세요. `오늘 무료
채팅`과 `body3Regular`, `n/3`, `body3Medium` 코드 스팬이 공백 없이 정확한 텍스트만 포함하도록 정리하세요.
In
`@Projects/Core/DesignSystem/Sources/Components/TodakHeader/DSTodakHeader.swift`:
- Around line 94-103: Update DSTodakHeader’s layout around rightItems and the
centered title to define a maximum visible right-action count or an explicit
overflow policy. Replace the fixed ZStack positioning with measurement-based
layout that reserves separate leading, title, and trailing regions, ensuring
right actions never overlap the title on narrow screens.
- Around line 139-148: Update the subtitle typography geometry call in
DSTodakHeader to build the debug name inline with string interpolation using
spec.subtitleFontStyle and spec.remainingCountFontStyle. Remove the
subtitleDebugTypographyName helper and ensure the inline expression is passed
directly to dsDebugTypographyGeometry so `@autoclosure` can avoid evaluating it in
Release builds.
- Line 110: Update DSTodakHeader’s Specification contract to add a
backgroundAsset and use it for the view’s background instead of directly
referencing DesignSystemAsset.Colors.white.swiftUIColor. Expose and map
backgroundAsset consistently with the other specification values, and extend
DSTodakHeaderSpecificationTests to verify its mapping.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 2ed2066f-84b0-4e9e-9877-1ac609739703
⛔ Files ignored due to path filters (4)
Projects/Core/DesignSystem/Docs/Images/Todak Header.pngis excluded by!**/*.pngProjects/Core/DesignSystem/Resources/Assets.xcassets/Icons/chat_add.imageset/chat_add.svgis excluded by!**/*.svgProjects/Core/DesignSystem/Resources/Assets.xcassets/Icons/delete_line.imageset/delete_line.svgis excluded by!**/*.svgProjects/Core/DesignSystem/Resources/Assets.xcassets/Icons/notes.imageset/notes.svgis excluded by!**/*.svg
📒 Files selected for processing (14)
Projects/Core/DesignSystem/Docs/Components/Todak_Header.mdProjects/Core/DesignSystem/Docs/Figma_Specification.mdProjects/Core/DesignSystem/Example/Sources/Catalogs/ColorCatalogView.swiftProjects/Core/DesignSystem/Example/Sources/Catalogs/ComponentsCatalogView.swiftProjects/Core/DesignSystem/Example/Sources/Playgrounds/TodakHeaderPlaygroundView.swiftProjects/Core/DesignSystem/Resources/Assets.xcassets/Colors/coolGray975.colorset/Contents.jsonProjects/Core/DesignSystem/Resources/Assets.xcassets/Icons/chat_add.imageset/Contents.jsonProjects/Core/DesignSystem/Resources/Assets.xcassets/Icons/delete_line.imageset/Contents.jsonProjects/Core/DesignSystem/Resources/Assets.xcassets/Icons/notes.imageset/Contents.jsonProjects/Core/DesignSystem/Sources/Components/TodakHeader/DSTodakHeader.swiftProjects/Core/DesignSystem/Sources/DesignSystemColor.swiftProjects/Core/DesignSystem/Sources/DesignSystemIcon.swiftProjects/Core/DesignSystem/Tests/DSIconAssetTests.swiftProjects/Core/DesignSystem/Tests/DSTodakHeaderSpecificationTests.swift
- 배경색을 Specification과 Example, 매핑 테스트에 연결합니다. - Release에서 디버그 타이포그래피 이름을 불필요하게 계산하지 않도록 호출부에서 직접 구성합니다. - Todak Header 명세의 Markdown code span 경고를 해소합니다.
There was a problem hiding this comment.
♻️ Duplicate comments (1)
Projects/Core/DesignSystem/Sources/Components/TodakHeader/DSTodakHeader.swift (1)
81-109:⚠️ Potential issue | 🟠 Major중앙 타이틀과 우측 액션의 겹침 정책을 정의해야 합니다.
ZStack에서 중앙titleGroup과 trailing 액션 영역이 독립적으로 배치되고rightItems개수도 제한되지 않아, 좁은 화면이나 3개 이상의 액션에서 버튼이 타이틀을 덮을 수 있습니다. 최대 개수/overflow 정책을 공개 계약으로 정하고, 측정 기반 레이아웃으로 leading·title·trailing 영역을 분리해 주세요. 정책을 변경하면Projects/Core/DesignSystem/Docs/Components/Todak_Header.md의 Layout Contract도 함께 갱신해야 합니다.최대 2개가 실제 계약이라면 최소한 초기화 시 명시적으로 검증할 수 있습니다.
수정 예시
public init( remainingFreeChatCount: Int, rightItems: [RightItem], onClose: `@escaping` () -> Void ) { + precondition(rightItems.count <= 2, "DSTodakHeader supports at most two right actions") self.remainingFreeChatCount = remainingFreeChatCountAs per coding guidelines, 작은 화면과 긴 텍스트에서도 UI가 겹치지 않는 레이아웃을 보장해야 합니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Projects/Core/DesignSystem/Sources/Components/TodakHeader/DSTodakHeader.swift` around lines 81 - 109, Define and enforce the public overlap policy for DSTodakHeader: constrain rightItems according to the intended maximum or implement an explicit overflow behavior, and replace the independent ZStack placement with measured leading, title, and trailing regions that prevent overlap on narrow screens and with long titles. If the contract is a maximum of two actions, validate that requirement during initialization. Update the Todak Header Layout Contract documentation whenever the policy changes.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In
`@Projects/Core/DesignSystem/Sources/Components/TodakHeader/DSTodakHeader.swift`:
- Around line 81-109: Define and enforce the public overlap policy for
DSTodakHeader: constrain rightItems according to the intended maximum or
implement an explicit overflow behavior, and replace the independent ZStack
placement with measured leading, title, and trailing regions that prevent
overlap on narrow screens and with long titles. If the contract is a maximum of
two actions, validate that requirement during initialization. Update the Todak
Header Layout Contract documentation whenever the policy changes.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 80e0226b-6528-46fe-8afa-6fa206eae450
📒 Files selected for processing (4)
Projects/Core/DesignSystem/Docs/Components/Todak_Header.mdProjects/Core/DesignSystem/Example/Sources/Playgrounds/TodakHeaderPlaygroundView.swiftProjects/Core/DesignSystem/Sources/Components/TodakHeader/DSTodakHeader.swiftProjects/Core/DesignSystem/Tests/DSTodakHeaderSpecificationTests.swift
- WheelPicker PR #42 변경사항을 Todak Header 작업 브랜치에 통합합니다. - DesignSystem 문서와 컴포넌트 카탈로그의 양쪽 등록을 함께 유지합니다. # Conflicts: # Projects/Core/DesignSystem/Example/Sources/Catalogs/ComponentsCatalogView.swift
- DSTodakHeader.RightItem을 제거하고 DSHeaderActionItem 공통 모델로 승격했습니다. - Todak Header 예제와 명세의 우측 액션 전달 타입을 공통 모델 기준으로 갱신했습니다.
# Conflicts: # Projects/Core/DesignSystem/Example/Sources/Catalogs/ComponentsCatalogView.swift # Projects/Core/DesignSystem/Sources/DesignSystemIcon.swift # Projects/Core/DesignSystem/Tests/DSIconAssetTests.swift
- 헤더 액션 입력 모델과 SwiftUI 렌더링 책임을 분리했습니다. - Todak Header의 고정·주입 액션이 공통 렌더러를 사용하도록 정리했습니다.
변경 내용
DSTodakHeader컴포넌트를 추가했습니다.토닥이오늘 무료 채팅 n/3형태의 잔여 횟수 표시DSHeaderActionItem으로 공통화했습니다.Components/Common으로 승격했습니다.body3Regular,gray500body3Medium,gray800body3Medium,gray500coolGray975,chatAdd,deleteLine,notes리소스와 타입 세이프 접근 API를 추가했습니다.고민한 내용
DSTodakHeader가 safe area까지 직접 소유하면 화면 컨테이너와 책임이 겹칠 수 있습니다. 따라서 컴포넌트는 48pt 높이의 실제 콘텐츠만 제공하고, 노치와 Dynamic Island 대응은 사용하는 화면의 safe area 배치에 맡겼습니다.remainingFreeChatCount는 서버 응답을 바탕으로 Feature 상태가 관리하는 값입니다. DesignSystem 내부에서 0...3 범위로 보정하면 실제 상태와 표시값이 달라질 수 있어, 별도의 clamp나Binding없이 전달받은 값을 그대로 표시하도록 구성했습니다.chatAdd,notes두 개가 기본 구성이지만, 컴포넌트에서 개수나 종류를 강제하지 않고rightItems배열로 받도록 했습니다. 버튼의 아이콘과 action은 사용하는 화면이 결정하고, 크기·간격·색상·pressed 스타일은 DesignSystem이 일관되게 관리합니다.DSHeaderActionItem이라는 공통 모델로 분리하고 배치 위치는 각 컴포넌트 API가 표현하도록 했습니다.Text를 결합했습니다. 화면에서는 하나의 텍스트처럼 배치되면서 각 구간의 명세를 독립적으로 유지할 수 있습니다.스크린샷
테스트
mise exec -- swiftlint --config .swiftlint.yml./scripts/validate-design-system-assets.sh./scripts/sync-and-validate.shPR Preflight Review
git diff --check,./scripts/validate-architecture.sh, pre-push SwiftLint 및 아키텍처 검증 통과참고 사항
chatAdd,notes두 개입니다.체크리스트
Closes #47
Summary by CodeRabbit
새 기능
문서
테스트