feat : 공통 컴포넌트 BottomSheet 추가 - #50
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughVaul 기반 공통 BottomSheet와 Pin 목록 시트, Song 선택 시트를 추가했습니다. 관련 도메인 타입, 카드, 정렬 탭, 검색 및 선택 상태 처리를 정의하고 TopBar 레이아웃을 flex 기반으로 변경했습니다. ChangesBottomSheet 및 Pin/Song 기능
TopBar 레이아웃
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant SongBottom
participant SearchInput
participant BottomSheet
participant SongCard
User->>SongBottom: 노래 선택 시트 열기 클릭
SongBottom->>BottomSheet: open=true 설정
User->>SearchInput: 검색어 입력
SearchInput->>SongBottom: query 변경 전달
SongBottom->>SongBottom: filteredSongs 계산
SongBottom->>SongCard: 필터링된 곡 목록 렌더링
User->>SongCard: 곡 선택
SongCard->>SongBottom: onClick 호출
SongBottom->>SongBottom: onSelect(song) 호출
SongBottom->>BottomSheet: 시트 닫기 및 query 초기화
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 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.
Actionable comments posted: 3
🧹 Nitpick comments (5)
src/features/pin/components/SongBottom.tsx (2)
8-11: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value타입명이 오해를 줍니다.
SongCardProps는 실제로SongPage(SongBottom) 컴포넌트의 props인데,SongCard.tsx에도 동일한 이름의 타입이 존재해 혼동을 줍니다.SongPageProps또는SongBottomProps로 리네임하는 것을 권장합니다.♻️ 제안
-type SongCardProps = { +type SongPageProps = { songs?: Song[]; onSelect?: (song: Song) => void; };🤖 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 `@src/features/pin/components/SongBottom.tsx` around lines 8 - 11, Rename the props type in SongBottom to avoid confusion with the similarly named type in SongCard; the current SongCardProps is misleading because it belongs to the SongBottom/SongPage component. Update the type name in SongBottom and any local references to a clearer identifier such as SongBottomProps or SongPageProps, keeping the props shape unchanged.
20-20: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueexport 방식이 다른 컴포넌트들과 불일치합니다.
BottomSheet,SongCard는 named export인데 이 컴포넌트만export default를 사용합니다. 또한 파일명(SongBottom.tsx)과 컴포넌트명(SongPage)도 일치하지 않아 import 시 혼란을 줄 수 있습니다.🤖 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 `@src/features/pin/components/SongBottom.tsx` at line 20, SongBottom.tsx has an export/name mismatch: the SongPage component is using export default while related components like BottomSheet and SongCard use named exports. Update SongPage to use the same named export style as the other components, and align the component name with the file’s purpose to avoid import confusion; keep the fix localized to SongPage and its export declaration.src/features/pin/components/PinCard.tsx (1)
7-7: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value타입명 오타:
PingCardProps→PinCardProps.컴포넌트명은
PinCard인데 타입명이PingCardProps로 오타가 있습니다. 로컬 타입이라 당장 문제는 없지만 가독성을 위해 수정하는 것을 권장합니다.🤖 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 `@src/features/pin/components/PinCard.tsx` at line 7, The local props type name in PinCard is misspelled as PingCardProps; rename it to PinCardProps in the PinCard component so the type matches the component name and improves readability. Update the type alias declaration and any nearby references in PinCard.tsx that use this props type to keep the naming consistent.src/features/pin/components/SortTabs.tsx (1)
16-35: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
aria-selected는role="tab"컨텍스트 없이 사용하면 의미가 명확하지 않습니다.일반
<button>에aria-selected를 붙이는 것은 ARIA 스펙상tab/tablist/tabpanel구조에서 사용하는 속성입니다. 탭 UI가 아니라면aria-pressed가 더 적절하고, 탭 UI로 의도한 것이라면 부모에role="tablist", 각 버튼에role="tab"을 추가해야 스크린리더가 올바르게 인식합니다.♿ 제안 수정 (tablist 구조로)
- <div className="flex w-full h-10 rounded-xl bg-pli-black-75 px-[4.5px] py-1 gap-[3px]"> + <div role="tablist" className="flex w-full h-10 rounded-xl bg-pli-black-75 px-[4.5px] py-1 gap-[3px]"> {OPTIONS.map((option) => { const selected = value === option.value; return ( <button key={option.value} type="button" + role="tab" aria-selected={selected}🤖 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 `@src/features/pin/components/SortTabs.tsx` around lines 16 - 35, The SortTabs buttons are using aria-selected without a tab context, so update the accessibility semantics in SortTabs to match the intended UI. If this is a tab interface, add role="tablist" to the container and role="tab" to each button in the OPTIONS map so aria-selected is valid; otherwise replace aria-selected with aria-pressed on the button elements. Keep the change localized to SortTabs and preserve the existing selected state logic.src/features/pin/components/PinListSheet.tsx (1)
15-53: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff미리보기용 mock 데이터와 트리거 버튼이 재사용 컴포넌트에 하드코딩되어 있습니다.
MOCK_PLACE,MOCK_PINS를 기본값으로 사용하고, 컴포넌트 내부에 "PIN 목록 바텀시트 미리보기" 안내 문구와 열기 버튼까지 포함되어 있습니다.PinListSheet는 지도/핀 조회 화면에서 재사용될 공통 시트 컴포넌트인데, 데모/미리보기 로직이 섞여 있어 실제 사용처(지도 클릭 시 열기 등)에 적용할 때 이 프리뷰 UI를 제거하는 별도 작업이 필요합니다. 미리보기는 Storybook이나 별도 데모 페이지로 분리하는 것을 권장합니다.🤖 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 `@src/features/pin/components/PinListSheet.tsx` around lines 15 - 53, `PinListSheet` is mixing reusable sheet behavior with demo-only mock data and trigger UI. Remove the `MOCK_PLACE` and `MOCK_PINS` default fallbacks from `PinListSheetProps` usage, and delete the hardcoded preview text/button inside `PinListSheet` so the component only renders the sheet itself. Keep the open/close trigger and any preview UX in a separate demo surface such as Storybook or a dedicated page, and update the `PinListSheet` component API to rely on real `place`, `pins`, and `onPinClick` inputs.
🤖 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 `@src/components/ui/BottomSheet.tsx`:
- Around line 17-41: `SheetContent` currently renders `DrawerPrimitive.Content`
without an accessible title, so add a `DrawerPrimitive.Title` inside the content
(or wrap the existing `Header` heading with it) to satisfy accessibility
requirements; if this sheet should be modal with a dimmed backdrop, also render
`DrawerPrimitive.Overlay` inside `SheetPortal` alongside
`DrawerPrimitive.Content` in `BottomSheet.tsx`.
In `@src/features/pin/components/PinCard.tsx`:
- Around line 7-20: `PinCard`에서 선언된 className prop이 전달받지 않고 button에 적용되지 않아 호출부
스타일이 무시됩니다. `PinCard`의 props 구조 분해에 className을 포함하고, 루트 `button`의 className에 기존
고정 클래스와 함께 병합되도록 수정하세요. `PingCardProps`와 `PinCard` 컴포넌트를 기준으로 찾아서, 전달된
className이 실제 렌더링에 반영되게 하면 됩니다.
In `@src/features/pin/components/SongBottom.tsx`:
- Around line 63-69: The SongBottom sheet click handler currently closes the
sheet without clearing the search state, so reopening preserves the previous
query. Update the SongCard onClick flow in SongBottom to also reset the local
query state when a song is selected, alongside onSelect and setOpen(false), so
the sheet reopens with a fresh search. Use the existing query state setter in
this component and keep the reset behavior tied to the same selection path.
---
Nitpick comments:
In `@src/features/pin/components/PinCard.tsx`:
- Line 7: The local props type name in PinCard is misspelled as PingCardProps;
rename it to PinCardProps in the PinCard component so the type matches the
component name and improves readability. Update the type alias declaration and
any nearby references in PinCard.tsx that use this props type to keep the naming
consistent.
In `@src/features/pin/components/PinListSheet.tsx`:
- Around line 15-53: `PinListSheet` is mixing reusable sheet behavior with
demo-only mock data and trigger UI. Remove the `MOCK_PLACE` and `MOCK_PINS`
default fallbacks from `PinListSheetProps` usage, and delete the hardcoded
preview text/button inside `PinListSheet` so the component only renders the
sheet itself. Keep the open/close trigger and any preview UX in a separate demo
surface such as Storybook or a dedicated page, and update the `PinListSheet`
component API to rely on real `place`, `pins`, and `onPinClick` inputs.
In `@src/features/pin/components/SongBottom.tsx`:
- Around line 8-11: Rename the props type in SongBottom to avoid confusion with
the similarly named type in SongCard; the current SongCardProps is misleading
because it belongs to the SongBottom/SongPage component. Update the type name in
SongBottom and any local references to a clearer identifier such as
SongBottomProps or SongPageProps, keeping the props shape unchanged.
- Line 20: SongBottom.tsx has an export/name mismatch: the SongPage component is
using export default while related components like BottomSheet and SongCard use
named exports. Update SongPage to use the same named export style as the other
components, and align the component name with the file’s purpose to avoid import
confusion; keep the fix localized to SongPage and its export declaration.
In `@src/features/pin/components/SortTabs.tsx`:
- Around line 16-35: The SortTabs buttons are using aria-selected without a tab
context, so update the accessibility semantics in SortTabs to match the intended
UI. If this is a tab interface, add role="tablist" to the container and
role="tab" to each button in the OPTIONS map so aria-selected is valid;
otherwise replace aria-selected with aria-pressed on the button elements. Keep
the change localized to SortTabs and preserve the existing selected state logic.
🪄 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: CHILL
Plan: Pro Plus
Run ID: ced5673a-1e74-4d9e-92ff-1b08c85955fb
⛔ Files ignored due to path filters (4)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yamlsrc/assets/icons/bookmark.svgis excluded by!**/*.svgsrc/assets/icons/heart.svgis excluded by!**/*.svgsrc/assets/icons/next.svgis excluded by!**/*.svg
📒 Files selected for processing (8)
package.jsonsrc/components/ui/BottomSheet.tsxsrc/features/pin/components/PinCard.tsxsrc/features/pin/components/PinListSheet.tsxsrc/features/pin/components/SongBottom.tsxsrc/features/pin/components/SongCard.tsxsrc/features/pin/components/SortTabs.tsxsrc/types/pin.ts
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@src/components/ui/TopBar.tsx`:
- Line 28: Update the TopBar layout around the div using justify-between so the
title remains geometrically centered regardless of back/close button widths or
missing callbacks. Use equal-width grid columns or independently center-position
the title, while preserving the existing button behavior and styling for screens
such as NicknameSetupPage.
🪄 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: CHILL
Plan: Pro Plus
Run ID: 826747c0-7d2b-4f87-89af-249f089bff8b
📒 Files selected for processing (1)
src/components/ui/TopBar.tsx
변경 내용
BottomSheet공통 컴포넌트를 추가했습니다.PinListSheet,PinCard,SortTabs)을 구현했습니다.?react방식으로 적용했습니다.PinSong,PlaceInfo,PinSort)을 정의했습니다.공통 컴포넌트
BottomSheet: 열림/닫힘, 스냅 포인트, 드래그 핸들BottomSheet.Header/Content/Footer/FullPageNav서브 컴포넌트PIN 도메인 컴포넌트
PinListSheet: 장소 정보, 북마크, 정렬 탭, PIN 카드 목록PinCard: 곡 정보, 좋아요 수, PIN 수 표시SortTabs: 인기순/최신순 탭SONG 도메인 컴포넌트
관련 이슈
Closes #8
Closes #13
변경 사항
테스트
스크린샷 (UI 변경시)


체크리스트
pnpm format)pnpm lint:fix)코드 품질 확인
PR 제출 전에 다음 명령어를 실행하여 코드 품질을 확인해주세요:
Summary by CodeRabbit
Summary