Design/#38 - Sidebar UI 및 SidebarFeature 구현 - #40
Conversation
|
Warning Review limit reached
Next review available in: 53 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: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
Walkthrough사이드바 필터·프로젝트 선택 기능을 TCA로 구현하고 MainFeature 및 NavigationSplitView에 연결했습니다. 사이드바 UI와 프로젝트 목록을 추가했으며, 카테고리와 프로젝트 컨테이너의 디자인 토큰 및 레이아웃을 조정했습니다. Changes메인 및 사이드바 UI
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant SidebarView
participant SidebarFeature
participant MainFeature
User->>SidebarView: 필터 또는 프로젝트 선택
SidebarView->>SidebarFeature: didSelect 전송
SidebarFeature->>SidebarFeature: selection 갱신
SidebarFeature->>MainFeature: selectionChanged delegate 전송
MainFeature-->>SidebarView: 스코프된 상태로 화면 갱신
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 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 |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
Projects/DVDesign/Sources/Components/DVCategory.swift (1)
98-103: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value불필요한
isHovered분기 제거
isHovered조건이 참일 때의 반환값과 조건문을 통과한 기본 반환값이 모두gray200으로 동일합니다. 중복되는 조건 분기를 제거하여 코드를 더 간결하게 유지하는 것을 제안합니다.💡 제안하는 수정안
private func backgroundColor(isPressed: Bool) -> Color { if isSelected { return Color.dv(.vaultGreen) } if isPressed { return Color.dv(.gray300) } - if isHovered { return Color.dv(.gray200) } return Color.dv(.gray200) }🤖 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/DVDesign/Sources/Components/DVCategory.swift` around lines 98 - 103, Remove the redundant isHovered branch from backgroundColor(isPressed:), since it returns the same gray200 color as the default path; preserve the isSelected and isPressed priority and keep gray200 as the fallback.
🤖 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.
Nitpick comments:
In `@Projects/DVDesign/Sources/Components/DVCategory.swift`:
- Around line 98-103: Remove the redundant isHovered branch from
backgroundColor(isPressed:), since it returns the same gray200 color as the
default path; preserve the isSelected and isPressed priority and keep gray200 as
the fallback.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: cc94e1fd-89d4-4aa9-ba86-7e3f75a636d8
📒 Files selected for processing (11)
Projects/DVDesign/Sources/Components/DVCategory.swiftProjects/DVDesign/Sources/Components/DVProjectContainer.swiftProjects/DVPresentation/Sources/Features/AppFeature.swiftProjects/DVPresentation/Sources/Features/AppView.swiftProjects/DVPresentation/Sources/Features/Main/MainFeature.swiftProjects/DVPresentation/Sources/Features/Main/MainView.swiftProjects/DVPresentation/Sources/Features/Sidebar/SidebarFeature.swiftProjects/DVPresentation/Sources/Features/Sidebar/SidebarView.swiftProjects/DVPresentation/Sources/ProjectSecretRelationDemoView.swiftProjects/DVPresentation/Sources/SecretUseCaseDemoView.swiftProjects/Devault/Sources/ContentView.swift
💤 Files with no reviewable changes (3)
- Projects/Devault/Sources/ContentView.swift
- Projects/DVPresentation/Sources/SecretUseCaseDemoView.swift
- Projects/DVPresentation/Sources/ProjectSecretRelationDemoView.swift
SidebarFilter, SidebarSelection enum 정의 및 SidebarFeature 구현. SidebarSelection으로 filter/project 선택을 단일 상태로 표현해 상호 배타성 보장.
Scope으로 SidebarFeature를 MainFeature에 연결하고 SidebarView를 MainView sidebar 컬럼에 주입.
DVCategory, DVProjectContainer 컴포넌트를 활용한 사이드바 UI 구현. filterGrid, projectSection, bottomBar로 구성.
| var title: String { | ||
| switch self { | ||
| case .all: "All" | ||
| case .starred: "Star" | ||
| case .expired: "Expired" | ||
| case .deleted: "Deleted" | ||
| } |
There was a problem hiding this comment.
로컬라이제이션: "All", "Star", "Project", "Rename" 등 모든 사용자 노출 문자열이 하드코딩. 후속 이슈로 관리하고 있는지 확인
외부 모듈에서 State를 관찰해야 하는 시점을 대비해 selection, isProjectSectionExpanded를 public internal(set)으로 변경. getter는 외부 공개, setter는 모듈 내부(reducer)만 접근 가능.
- List maxHeight 제한 제거 - 접근성 레이블 추가: Add Project, Collapse/Expand Projects, Settings, Add Secret - 프리뷰를 Group으로 통합, 너비 200/250/270pt 대응 - collapsed 시 Spacer(minLength: 0) 추가로 bottomBar 하단 고정 버그 수정 - List deselect nil 처리 TODO 주석 추가
TODO 목록Localization
접근성 (Accessibility)
기능 구현
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
Projects/DVDesign/Sources/Components/DVCategory.swift (1)
92-102: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win버튼 눌림(Pressed) 상태에 대한 시각적 피드백을 추가하세요.
현재
makeBody에서configuration.isPressed에 대한 처리가 누락되어 클릭 시 반응이 없습니다. macOS 환경에서는 마우스 상호작용이 주가 되므로 클릭 피드백이 필수적입니다.
또한, SwiftUI 뷰 구조 가이드라인에 따라 파라미터가 있는 하위 뷰/로직은private func로 정의해야 합니다.💡 제안하는 수정안
func makeBody(configuration: Configuration) -> some View { configuration.label - .background(backgroundColor) + .background(backgroundColor(isPressed: configuration.isPressed)) .clipShape(RoundedRectangle(cornerRadius: 16)) } - private var backgroundColor: Color { + private func backgroundColor(isPressed: Bool) -> Color { + if isPressed { return Color.dv(.gray400) } // 적절한 Pressed 색상으로 변경 if isSelected { return Color.dv(.vaultGreen) } if isHovered { return Color.dv(.gray300) } return Color.dv(.gray200) }🤖 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/DVDesign/Sources/Components/DVCategory.swift` around lines 92 - 102, Update makeBody(configuration:) to provide visual feedback when configuration.isPressed is true, while preserving the selected, hovered, and default background behavior. Move the parameter-dependent background selection logic out of the parameterless backgroundColor property into a private function that accepts the button configuration or pressed state, and use it from makeBody.Source: Path instructions
🤖 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.
Nitpick comments:
In `@Projects/DVDesign/Sources/Components/DVCategory.swift`:
- Around line 92-102: Update makeBody(configuration:) to provide visual feedback
when configuration.isPressed is true, while preserving the selected, hovered,
and default background behavior. Move the parameter-dependent background
selection logic out of the parameterless backgroundColor property into a private
function that accepts the button configuration or pressed state, and use it from
makeBody.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 015f101e-4dba-4ea5-94e6-e4df2c0a4b04
📒 Files selected for processing (5)
Projects/DVDesign/Resources/Assets.xcassets/color/gray300.colorset/Contents.jsonProjects/DVDesign/Sources/Components/DVCategory.swiftProjects/DVPresentation/Sources/Features/Main/MainView.swiftProjects/DVPresentation/Sources/Features/Sidebar/SidebarFeature.swiftProjects/DVPresentation/Sources/Features/Sidebar/SidebarView.swift
🚧 Files skipped from review as they are similar to previous changes (3)
- Projects/DVPresentation/Sources/Features/Main/MainView.swift
- Projects/DVPresentation/Sources/Features/Sidebar/SidebarView.swift
- Projects/DVPresentation/Sources/Features/Sidebar/SidebarFeature.swift
✨ What’s this PR?
📌 관련 이슈 (Related Issue)
🧶 주요 변경 내용 (Summary)
📸 스크린샷 (Optional)
🧪 테스트 / 검증 내역
💬 기타 공유 사항
SidebarSelection enum 도입
filter 선택과 project 선택은 동시에 존재할 수 없는 상호 배타적 상태.
selectedFilter + selectedProjectIndex두 프로퍼티로 분리하면 둘이 동시에 값을 갖는 잘못된 상태가 모델링 가능하므로,SidebarSelectionenum 하나로 통합해 타입 시스템에서 불가능하게 만들었습니다.List selection Binding 처리
List(selection:)은Binding<Int?>를 요구하지만 store의 selection은SidebarSelection(enum)이라 타입 불일치로$store직접 바인딩이 불가합니다.가이드라인(8.4)를 벗어나지만, 의도적 예외이므로 주석으로 이유를 명시했습니다.
List selection 컬러
macOS List
.sidebar스타일의 selection 하이라이트 색상은.tint()로 변경 불가 — 시스템 Accent Color를 강제 사용합니다.NSAccentColorNameasset 방식도 시도했으나 동작하지 않아 시스템 컬러로 유지합니다.List 가로 패딩
사이드바 전체에
.padding(.horizontal, 12)를 적용하되, List만.padding(.horizontal, -12)로 상쇄해 List가 사이드바 전체 너비를 사용하도록 처리했습니다.아무래도... 다크모드 대응이 필수일 듯 합니다..
🙇🏻♀️ 리뷰 가이드 (선택)
추후 예정 작업
contextMenuAction 구현 (Rename, New Secret, Delete Project)MainFeature.handleSidebarDelegate실제 구현 (현재 모두 .none)Summary by CodeRabbit