Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[REFACTOR] BottomSheet width 값 조절과 포지셔닝, close 버튼 추가 #59

Merged
merged 5 commits into from
Nov 26, 2024

Conversation

houony
Copy link
Collaborator

@houony houony commented Nov 21, 2024

관련 이슈

close #58

📑 작업 내용

  • 바텀시트 최대 높이를 컨텐츠 높이로 설정했습니다
  • 바텀시트 위치와 width를 left-0 right-0 m-auto max-w-[30rem]로 맞췄습니다.
  • 바텀시트 헤더에 바텀시트를 닫을 수 있도록 deleteRound 버튼을 가져와 추가했습니다.

💬 리뷰 중점 사항/기타 참고 사항

Summary by CodeRabbit

  • 새로운 기능

    • BottomSheet 컴포넌트의 콘텐츠 구조가 개선되어 여러 개의 내용이 추가됨.
    • BottomSheet의 레이아웃과 애니메이션 동작이 향상됨.
    • 바텀 시트의 드래그 이벤트 처리 로직이 개선되어 높이 조정이 더 동적으로 이루어짐.
  • 버그 수정

    • 바텀 시트의 최대 높이 계산 방식이 개선됨.

@houony houony self-assigned this Nov 21, 2024
@houony houony requested a review from keemsebin as a code owner November 21, 2024 04:35
Copy link

coderabbitai bot commented Nov 21, 2024

Walkthrough

이 풀 리퀘스트는 BottomSheet 컴포넌트와 관련된 여러 파일에서의 변경 사항을 포함하고 있습니다. BottomSheet의 스토리북 구성에서 콘텐츠가 여러 <div> 요소로 변경되었으며, 컴포넌트의 레이아웃과 애니메이션 동작이 개선되었습니다. 또한, 상수 값들이 조정되었고, useBottomSheet 훅에서 드래그 이벤트 처리 로직이 강화되었습니다. 이러한 변경은 BottomSheet의 크기 조절 및 상태 관리 기능을 향상시키기 위한 것입니다.

Changes

파일 경로 변경 요약
src/components/common/BottomSheet/BottomSheet.stories.tsx Basic 스토리의 콘텐츠가 여러 <div> 요소로 변경됨.
src/components/common/BottomSheet/index.tsx motion.div의 클래스 이름이 변경되고, initial prop이 추가됨.
src/constants/bottomSheetOptions.ts INITIAL_HEIGHT가 150에서 130으로 변경됨. MAX_HEIGHT 계산 방식이 수정됨.
src/hooks/common/useBottomSheet.tsx 드래그 이벤트 처리 로직이 개선되고, contentHeight 변수가 추가됨. handleDragEnd 함수 수정됨.

Assessment against linked issues

Objective Addressed Explanation
BottomSheet 크기 조절 (#58)
close 버튼 추가 (#58) close 버튼 추가에 대한 변경 사항 없음.

Possibly related PRs

Suggested reviewers

  • keemsebin

📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 6a3721c and 487a669.

📒 Files selected for processing (1)
  • src/components/common/BottomSheet/index.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/common/BottomSheet/index.tsx

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

github-actions bot commented Nov 21, 2024

Update: 2024년 11월 26일 00시 57분 23초
Storybook 미리보기: https://6709628f8a6eec04b29d4f39-lhmzrydoif.chromatic.com/

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (5)
src/components/common/BottomSheet/BottomSheetHeader.types.ts (1)

1-3: 타입 정의가 명확하고 PR 목적에 부합합니다.

타입 정의가 잘 되어있으며, BottomSheet의 닫기 기능을 위한 Props 인터페이스가 적절하게 구현되었습니다.

더 나은 문서화를 위해 JSDoc 주석을 추가하는 것을 추천드립니다:

+/**
+ * BottomSheetHeader 컴포넌트의 Props
+ */
 export type Props = {
+  /** BottomSheet의 열림/닫힘 상태를 제어하는 함수 */
   setIsOpen: (value: boolean) => void;
 };
src/components/common/BottomSheet/BottomSheetHeader.tsx (2)

5-8: handleClose 함수의 최적화를 고려해보세요.

handleClose 함수를 useCallback으로 메모이제이션하면 불필요한 리렌더링을 방지할 수 있습니다.

다음과 같이 수정하는 것을 추천드립니다:

+import { useCallback } from 'react';
 import { Props } from './BottomSheetHeader.types';

 export const BottomSheetHeader = ({ setIsOpen }: Props) => {
-  const handleClose = () => {
+  const handleClose = useCallback(() => {
     setIsOpen(false);
-  };
+  }, [setIsOpen]);

11-12: 반응형 디자인 고려사항

현재 구현된 고정 너비(w-20)와 높이(h-1.5) 값들이 모든 화면 크기에서 적절할지 검토가 필요합니다.

다음과 같이 반응형 클래스를 추가하는 것을 고려해보세요:

-      <div className="w-20 h-1.5 bg-primary mx-auto rounded-full" />
+      <div className="w-16 md:w-20 h-1 md:h-1.5 bg-primary mx-auto rounded-full" />
src/hooks/common/useBottomSheet.tsx (2)

49-54: 스크롤 높이 계산 최적화 제안

scrollHeight 속성을 매 애니메이션 프레임마다 읽는 것은 성능에 영향을 줄 수 있습니다. 컨텐츠가 자주 변경되지 않는다면, useEffect를 사용하여 컨텐츠가 변경될 때만 높이를 계산하는 것이 좋습니다.

다음과 같이 최적화할 수 있습니다:

+const contentHeightRef = useRef<number>(MAX_HEIGHT);
+
+useEffect(() => {
+  contentHeightRef.current = bottomSheetRef.current?.scrollHeight || MAX_HEIGHT;
+}, [isOpen]); // isOpen이 변경될 때만 높이를 다시 계산
+
 const handleDrag = useCallback(
   (_: MouseEvent | TouchEvent | PointerEvent, info: DragInfo) => {
     if (isInteractionDisabled) return;
     requestAnimationFrame(() => {
       const dragAmount = -info.delta.y;
       dragOffsetRef.current += dragAmount * 5;
-      const contentHeight = bottomSheetRef.current?.scrollHeight || MAX_HEIGHT;
       const newHeight = Math.min(
         Math.max(initialPositionRef.current + dragOffsetRef.current, MIN_VISIBLE_HEIGHT),
-        Math.min(contentHeight, MAX_HEIGHT)
+        Math.min(contentHeightRef.current, MAX_HEIGHT)
       );

72-74: 상태 초기화 로직 개선

드래그 종료 시 상태 초기화 로직이 추가되었습니다. 코드의 가독성과 유지보수성을 높이기 위해 초기화 로직을 별도의 함수로 분리하는 것이 좋습니다.

다음과 같이 리팩토링을 제안합니다:

+const resetDragState = (height: number) => {
+  initialPositionRef.current = height;
+  dragOffsetRef.current = 0;
+};
+
 const handleDragEnd = useCallback(() => {
   if (sheetHeight <= MIN_VISIBLE_HEIGHT) {
     setIsOpen(false);
     setIsInteractionDisabled(true);
+    resetDragState(INITIAL_HEIGHT);
     return;
   }

   if (sheetHeight > MAX_HEIGHT) {
     setSheetHeight(MAX_HEIGHT);
+    resetDragState(MAX_HEIGHT);
     return;
   }

-  initialPositionRef.current = sheetHeight;
-  dragOffsetRef.current = 0;
+  resetDragState(sheetHeight);
 }, [setIsOpen, sheetHeight]);
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between f18cd5a and 2efd24f.

📒 Files selected for processing (6)
  • src/components/common/BottomSheet/BottomSheet.stories.tsx (1 hunks)
  • src/components/common/BottomSheet/BottomSheetHeader.tsx (1 hunks)
  • src/components/common/BottomSheet/BottomSheetHeader.types.ts (1 hunks)
  • src/components/common/BottomSheet/index.tsx (1 hunks)
  • src/constants/bottomSheetOptions.ts (1 hunks)
  • src/hooks/common/useBottomSheet.tsx (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/components/common/BottomSheet/BottomSheet.stories.tsx
🔇 Additional comments (6)
src/constants/bottomSheetOptions.ts (2)

3-3: SSR 대응과 높이 조정이 개선되었습니다

다음과 같은 개선사항이 확인됩니다:

  1. typeof window !== 'undefined' 체크를 통해 SSR 호환성이 향상되었습니다
  2. 최대 높이가 window 높이의 80%로 조정되어 더 나은 사용성을 제공할 것으로 예상됩니다
  3. 기본값 800px 설정으로 안정성이 향상되었습니다
✅ Verification successful

바텀시트 높이 조정 및 SSR 대응이 적절히 구현되었습니다

검증 결과 다음 사항들이 확인되었습니다:

  • useBottomSheet 훅에서 MAX_HEIGHT가 적절히 활용되어 바텀시트의 최대 높이를 제한하고 있습니다
  • 컨텐츠 높이와 MAX_HEIGHT를 비교하여 적절한 높이 제어가 이루어지고 있습니다
  • SSR 대응을 위한 window 객체 체크와 기본값 설정이 올바르게 구현되어 있습니다
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify MAX_HEIGHT usage in components
# and check for any potential layout issues

# Search for MAX_HEIGHT usage
rg -A 5 "MAX_HEIGHT" --type ts --type tsx

# Look for any height-related style definitions
ast-grep --pattern 'style={$_height$_}'

Length of output: 111


Script:

#!/bin/bash
# Search for MAX_HEIGHT usage with correct file type
rg -A 5 "MAX_HEIGHT" -t ts -t typescript -t jsx -t tsx

# Look for style definitions containing height
rg -A 3 "style.*height" -t ts -t typescript -t jsx -t tsx

# Check if the constant is imported and used in other files
rg "import.*MAX_HEIGHT.*from.*constants" -t ts -t typescript -t jsx -t tsx

Length of output: 296


Script:

#!/bin/bash
# Search for MAX_HEIGHT usage
rg -A 5 "MAX_HEIGHT"

# Look for style definitions containing height
rg -A 3 "style.*height"

# Find all TypeScript/JavaScript files that might use MAX_HEIGHT
fd "\.(ts|tsx|js|jsx)$" -x grep -l "MAX_HEIGHT" {}

Length of output: 2816


1-2: INITIAL_HEIGHT와 MIN_VISIBLE_HEIGHT 간의 관계 확인 필요

INITIAL_HEIGHT가 130px로 감소되었습니다. MIN_VISIBLE_HEIGHT가 60px로 설정된 것을 고려할 때, 두 값의 차이(70px)가 드래그 상호작용에 충분한지 확인이 필요합니다.

src/components/common/BottomSheet/BottomSheetHeader.tsx (1)

1-3: 타입과 컴포넌트 임포트가 깔끔하게 구성되었습니다!

컴포넌트와 타입을 분리하여 임포트한 구조가 잘 정리되어 있습니다.

src/components/common/BottomSheet/index.tsx (3)

22-22: 스타일링 개선사항 검토 필요

className에서 동적 높이를 템플릿 리터럴로 처리하는 부분이 잠재적인 문제를 일으킬 수 있습니다. sheetHeight가 undefined일 경우 스타일이 깨질 수 있습니다.

다음과 같이 개선하는 것을 고려해보세요:

-className="absolute bottom-0 left-0 right-0 m-auto max-w-[30rem] h-${sheetHeight} bg-white shadow-[0px_-4px_10px_0px_rgba(0,0,0,0.1)] rounded-t-3xl p-4 overflow-hidden z-40"
+className={`absolute bottom-0 left-0 right-0 m-auto max-w-[30rem] ${
+  sheetHeight ? `h-[${sheetHeight}]` : 'h-0'
+} bg-white shadow-[0px_-4px_10px_0px_rgba(0,0,0,0.1)] rounded-t-3xl p-4 overflow-hidden z-40`}

29-33: 애니메이션 구현이 적절해 보입니다

initial 상태 추가와 BOTTOM_SHEET_ANIMATION 상수 활용이 자연스러운 동작을 만들어냅니다. 특히 height: 0부터 시작하는 것이 좋은 선택입니다.


35-35: 타입 안전성 확인 필요

BottomSheetHeader에 setIsOpen prop이 전달되었습니다. 연관된 타입 정의를 확인해주세요.

✅ Verification successful

The search results show that BottomSheetHeader has proper type definitions in src/components/common/BottomSheet/BottomSheetHeader.types.ts with setIsOpen correctly typed as (value: boolean) => void. This matches the usage in the code snippet. I can now generate the final response:

타입 정의가 올바르게 되어있음을 확인했습니다

BottomSheetHeader 컴포넌트의 Props 타입에 setIsOpen이 (value: boolean) => void로 정확하게 정의되어 있습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify type definitions for BottomSheetHeader
ast-grep --pattern 'type Props = {
  $$$
  setIsOpen: $_
  $$$
}'

Length of output: 1259

Comment on lines 13 to 15
<button onClick={handleClose} className="absolute right-4 top-0" aria-label="Close">
<Icon name="deleteRound" size={24} />
</button>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

접근성 개선 사항을 제안드립니다.

현재 기본적인 접근성이 구현되어 있으나, 다음과 같은 개선사항들을 고려해보시면 좋겠습니다:

다음과 같이 수정하는 것을 추천드립니다:

-      <button onClick={handleClose} className="absolute right-4 top-0" aria-label="Close">
+      <button
+        onClick={handleClose}
+        className="absolute right-4 top-0 p-2 hover:bg-gray-100 rounded-full transition-colors"
+        aria-label="바텀시트 닫기"
+        type="button"
+      >
         <Icon name="deleteRound" size={24} />
       </button>

변경사항:

  1. 한글 aria-label 추가
  2. 버튼 타입 명시
  3. 호버 상태 추가로 상호작용 피드백 개선
  4. 터치 영역 확장을 위한 패딩 추가
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<button onClick={handleClose} className="absolute right-4 top-0" aria-label="Close">
<Icon name="deleteRound" size={24} />
</button>
<button
onClick={handleClose}
className="absolute right-4 top-0 p-2 hover:bg-gray-100 rounded-full transition-colors"
aria-label="바텀시트 닫기"
type="button"
>
<Icon name="deleteRound" size={24} />
</button>

@@ -19,13 +19,14 @@ export const BottomSheet = memo(({ children, isOpen, setIsOpen }: Props) => {
<Portal isOpen={isOpen}>
<motion.div
ref={bottomSheetRef}
className="absolute bottom-0 left-0 w-full bg-white shadow-[0px_-4px_10px_0px_rgba(0,0,0,0.1)] rounded-t-3xl p-4 overflow-hidden z-40 h-${sheetHeight}"
className="absolute bottom-0 left-0 right-0 m-auto max-w-[30rem] h-${sheetHeight} bg-white shadow-[0px_-4px_10px_0px_rgba(0,0,0,0.1)] rounded-t-3xl p-4 overflow-hidden z-40"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

벡틱으로 감싸야 동적으로 sheetHeight 반영가능할 거 같아요~!

Suggested change
className="absolute bottom-0 left-0 right-0 m-auto max-w-[30rem] h-${sheetHeight} bg-white shadow-[0px_-4px_10px_0px_rgba(0,0,0,0.1)] rounded-t-3xl p-4 overflow-hidden z-40"
className={`absolute bottom-0 left-0 right-0 m-auto max-w-[30rem] h-${sheetHeight} bg-white shadow-[0px_-4px_10px_0px_rgba(0,0,0,0.1)] rounded-t-3xl p-4 overflow-hidden z-40`}

Copy link
Member

@keemsebin keemsebin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다~~

@houony houony merged commit db3c3bf into main Nov 26, 2024
5 checks passed
@keemsebin keemsebin deleted the refactor/#58-bottomsheet branch November 26, 2024 07:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[REFACTOR] BottomSheet 크기 조절, close 버튼 추가
2 participants