Skip to content

feat: BottomSheet 컴포넌트 구현 (#54)#60

Merged
wkdtnqls0506 merged 10 commits intomainfrom
feature/PRODUCT-112
Jul 3, 2025
Merged

feat: BottomSheet 컴포넌트 구현 (#54)#60
wkdtnqls0506 merged 10 commits intomainfrom
feature/PRODUCT-112

Conversation

@wkdtnqls0506
Copy link
Contributor

@wkdtnqls0506 wkdtnqls0506 commented Jun 30, 2025

✅ 이슈 번호

close #54


🪄 작업 내용 (변경 사항)

  • BottomSheet 컴포넌트 생성
    • src/components/ui/BottomSheet

📸 스크린샷

2025-07-01.1.52.50.mov

💡 설명

<BottomSheet
  open={isOpen}
  onOpenChange={setIsOpen}
  title="서비스 필수 이용약관"
  trigger={<button>바텀시트 열기</button>}
  footer={
    <Button
      size="fullWidth"
      onClick={() => {
        handleSubmit(onSubmit)();
        setIsOpen(false);
      }}
    >
      확인
    </Button>
  }
>
  <h2 className={mainTitle}>비밀번호를 변경해 안내 설명</h2>
  <p className={mainDescription}>
    회원님의 개인정보 보호를 위해 장기간 비밀번호를 유지 중인 경우
    비밀번호 변경을 안내해 드리고 있습니다.
  </p>
</BottomSheet>
props 설명
open 바텀시트 열림 여부를 제어합니다
onOpenChange 바텀시트 열림 상태가 변경될 때 호출되는 핸들러입니다
children 바텀시트 본문 내용입니다
title 바텀시트 상단에 표시될 제목입니다
trigger 바텀시트를 열기 위한 트리거 엘리먼트입니다
footer 바텀시트 하단 영역에 렌더링되는 콘텐츠입니다

🗣️ 리뷰어에게 전달 사항

  1. BottomSheet 버튼 관련
    바텀시트 하단에 버튼이 항상 true 값이긴 한데, 버튼의 텍스트나 클릭 시 동작까지 BottomSheet가 직접 책임지는 게 맞을까? 하는 고민이 들었습니다..🤔
    BottomSheet는 레이아웃 + 열고 닫는 동작까지만 책임지고, 버튼의 실제 로직은 사용하는 쪽에서 유연하게 받는 게 맞겠다고 판단했습니다..!
    그래서 하단 버튼은 footer props로 분리해서 버튼 props의 값을 외부에서 자유롭게 제어할 수 있는 구조로 구성했습니다!

  2. BottomSheet min-height 관련
    피그마 상에 정해진 값이 없는 거 같아서 일단 코멘트 남겨둔 상태입니다!
    값이 정해진다면 다시 수정해서 올리겠습니다 ㅎㅎ


📍 트러블 슈팅

Summary by CodeRabbit

  • 신규 기능

    • 새로운 BottomSheet UI 컴포넌트가 추가되어 하단 시트 형태의 인터페이스를 사용할 수 있습니다.
    • BottomSheet는 제목, 본문, 푸터(버튼 등), 트리거 버튼 등을 지원하며, Storybook에서 다양한 예시를 확인할 수 있습니다.
  • 스타일

    • BottomSheet 컴포넌트의 전용 스타일이 추가되어, 오버레이, 핸들, 컨텐츠, 버튼 영역 등 다양한 부분의 시각적 요소가 개선되었습니다.
    • 버튼 컴포넌트의 작은 크기 변형 스타일이 조정되었습니다.
  • 문서화

    • BottomSheet 컴포넌트의 사용법과 동작 예시가 Storybook 스토리로 제공됩니다.
    • Storybook 설정이 최신 버전으로 업데이트되고, 접근성(a11y) 테스트 설정이 추가되었습니다.
  • Chores

    • "vaul" 패키지가 신규로 추가되었습니다.
    • Storybook 관련 패키지들이 최신 버전으로 업그레이드되고 구성 방식이 개선되었습니다.

@wkdtnqls0506 wkdtnqls0506 added the ✨ feature 새로운 기능 추가 label Jun 30, 2025
@coderabbitai
Copy link

coderabbitai bot commented Jun 30, 2025

"""

Walkthrough

BottomSheet UI 컴포넌트가 새롭게 추가되었습니다. 컴포넌트의 스타일, 구현, Storybook 스토리, 그리고 관련 의존성(vaul)이 반영되었습니다. index 파일을 통해 컴포넌트가 외부로 공개됩니다.

Changes

파일/경로 변경 요약
package.json vaul 런타임 의존성 추가 및 Storybook 관련 devDependencies 업그레이드 및 변경
src/components/ui/BottomSheet/BottomSheet.css.ts BottomSheet 컴포넌트용 CSS 스타일 정의 및 내보내기
src/components/ui/BottomSheet/BottomSheet.tsx BottomSheet 컴포넌트 구현 및 내보내기
src/components/ui/BottomSheet/BottomSheet.stories.tsx BottomSheet Storybook 스토리 및 Wrapper 컴포넌트 추가
src/components/ui/BottomSheet/index.ts BottomSheet 컴포넌트 재내보내기
.storybook/main.ts Storybook 설정 변경: addons, framework, features, viteFinal 수정
.storybook/preview.ts Storybook preview 타입 변경 및 a11y 설정 추가
.storybook/vitest.setup.ts Storybook vitest setup import 경로 및 스타일 변경
src/components/ui/Button/Button.css.ts Button 컴포넌트 small 사이즈 스타일 패딩 및 크기 조정
src/components/ui/Button/Button.stories.tsx Storybook 타입 import 경로 변경
src/components/ui/TextField/TextField.stories.tsx Storybook 타입 import 경로 변경
.github/workflows/chromatic.yml PR 코멘트 메시지 포맷 수정 (별표 제거)

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant TriggerButton
    participant BottomSheet
    participant VaulDrawer

    User->>TriggerButton: 클릭
    TriggerButton->>BottomSheet: open 상태 변경
    BottomSheet->>VaulDrawer: open 상태 전달
    VaulDrawer->>BottomSheet: onOpenChange 콜백
    BottomSheet->>User: 하위 children, title, footer 렌더링
Loading

Assessment against linked issues

Objective (이슈 번호) Addressed Explanation
BottomSheet 컴포넌트 생성 (#54)
Storybook 생성 (#54)

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Button 컴포넌트 small 사이즈 스타일 변경 (src/components/ui/Button/Button.css.ts) BottomSheet 생성 이슈와 직접 관련 없는 UI 버튼 스타일 조정임
Storybook 설정 및 타입 import 변경 (.storybook/main.ts, .storybook/preview.ts, .storybook/vitest.setup.ts) BottomSheet 컴포넌트 생성과 직접 관련 없는 Storybook 환경 업그레이드 및 설정 변경
PR 코멘트 메시지 포맷 수정 (.github/workflows/chromatic.yml) BottomSheet 기능과 무관한 CI 워크플로우 메시지 포맷 수정임

Suggested reviewers

  • Seojunhwan

Poem

🐰
바닥에서 살짝 올라온 시트,
토끼가 눌러보니 참 예쁘지!
버튼도, 타이틀도, 발밑에 쏙—
Storybook 속에서 토글하며 똑똑!
새로운 컴포넌트, 만세를 외치네!
⬆️⬇️

"""

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

src/components/ui/BottomSheet/BottomSheet.stories.tsx

Oops! Something went wrong! :(

ESLint: 9.27.0

ESLint couldn't find the plugin "eslint-plugin-react-hooks".

(The package "eslint-plugin-react-hooks" was not found when loaded as a Node module from the directory "".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-react-hooks@latest --save-dev

The plugin "eslint-plugin-react-hooks" was referenced from the config file in " » eslint-config-next/core-web-vitals » /node_modules/.pnpm/eslint-config-next@15.3.2_eslint@9.27.0_jiti@2.4.2__typescript@5.8.3/node_modules/eslint-config-next/index.js".

If you still can't figure out the problem, please see https://eslint.org/docs/latest/use/troubleshooting.

.storybook/main.ts

Oops! Something went wrong! :(

ESLint: 9.27.0

ESLint couldn't find the plugin "eslint-plugin-react-hooks".

(The package "eslint-plugin-react-hooks" was not found when loaded as a Node module from the directory "".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-react-hooks@latest --save-dev

The plugin "eslint-plugin-react-hooks" was referenced from the config file in " » eslint-config-next/core-web-vitals » /node_modules/.pnpm/eslint-config-next@15.3.2_eslint@9.27.0_jiti@2.4.2__typescript@5.8.3/node_modules/eslint-config-next/index.js".

If you still can't figure out the problem, please see https://eslint.org/docs/latest/use/troubleshooting.

.storybook/vitest.setup.ts

Oops! Something went wrong! :(

ESLint: 9.27.0

ESLint couldn't find the plugin "eslint-plugin-react-hooks".

(The package "eslint-plugin-react-hooks" was not found when loaded as a Node module from the directory "".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-react-hooks@latest --save-dev

The plugin "eslint-plugin-react-hooks" was referenced from the config file in " » eslint-config-next/core-web-vitals » /node_modules/.pnpm/eslint-config-next@15.3.2_eslint@9.27.0_jiti@2.4.2__typescript@5.8.3/node_modules/eslint-config-next/index.js".

If you still can't figure out the problem, please see https://eslint.org/docs/latest/use/troubleshooting.

  • 7 others

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0810669 and c2ae013.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (12)
  • .github/workflows/chromatic.yml (1 hunks)
  • .storybook/main.ts (1 hunks)
  • .storybook/preview.ts (2 hunks)
  • .storybook/vitest.setup.ts (1 hunks)
  • package.json (3 hunks)
  • src/components/ui/BottomSheet/BottomSheet.css.ts (1 hunks)
  • src/components/ui/BottomSheet/BottomSheet.stories.tsx (1 hunks)
  • src/components/ui/BottomSheet/BottomSheet.tsx (1 hunks)
  • src/components/ui/BottomSheet/index.ts (1 hunks)
  • src/components/ui/Button/Button.css.ts (1 hunks)
  • src/components/ui/Button/Button.stories.tsx (1 hunks)
  • src/components/ui/TextField/TextField.stories.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • .storybook/vitest.setup.ts
  • src/components/ui/TextField/TextField.stories.tsx
🚧 Files skipped from review as they are similar to previous changes (10)
  • src/components/ui/BottomSheet/index.ts
  • src/components/ui/Button/Button.stories.tsx
  • src/components/ui/Button/Button.css.ts
  • .github/workflows/chromatic.yml
  • .storybook/preview.ts
  • src/components/ui/BottomSheet/BottomSheet.tsx
  • package.json
  • src/components/ui/BottomSheet/BottomSheet.stories.tsx
  • .storybook/main.ts
  • src/components/ui/BottomSheet/BottomSheet.css.ts
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
✨ Finishing Touches
  • 📝 Generate Docstrings

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.

❤️ 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this 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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

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.

@github-actions
Copy link

github-actions bot commented Jun 30, 2025

🎨 Storybook Preview: https://685a32a1c0bbd269fdb67af4-jlivhkkzuz.chromatic.com/
🔗 Chromatic Build: https://www.chromatic.com/build?appId=685a32a1c0bbd269fdb67af4&number=62
🕖 Updated at: 2025년 07월 04일 00시 57분 29초

@github-actions
Copy link

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: 3

🧹 Nitpick comments (1)
src/components/ui/BottomSheet/BottomSheet.css.ts (1)

26-29: TODO 주석 해결 필요

minHeight 값에 대한 디자이너 논의가 필요하다는 TODO 주석이 있습니다. 디자인 시스템과 일치하도록 이 값을 확정해주세요.

디자이너와의 논의 후 이 값을 업데이트하는 이슈를 생성하거나 PR을 작성해드릴까요?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9565453 and f6cb340.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (5)
  • package.json (1 hunks)
  • src/components/ui/BottomSheet/BottomSheet.css.ts (1 hunks)
  • src/components/ui/BottomSheet/BottomSheet.stories.tsx (1 hunks)
  • src/components/ui/BottomSheet/BottomSheet.tsx (1 hunks)
  • src/components/ui/BottomSheet/index.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
`{src/app/**/_components/*.{ts,tsx},src/components/**/*.{ts,tsx}}`: 컴포넌트 파일은 PascalCase로 네이밍해야 한다 (예: `Button.tsx`, `DomainLayout.tsx`).

{src/app/**/_components/*.{ts,tsx},src/components/**/*.{ts,tsx}}: 컴포넌트 파일은 PascalCase로 네이밍해야 한다 (예: Button.tsx, DomainLayout.tsx).

📄 Source: CodeRabbit Inference Engine (.cursor/rules/nextjs-folder-structure.mdc)

List of files the instruction was applied to:

  • src/components/ui/BottomSheet/index.ts
  • src/components/ui/BottomSheet/BottomSheet.tsx
  • src/components/ui/BottomSheet/BottomSheet.css.ts
  • src/components/ui/BottomSheet/BottomSheet.stories.tsx
`**/*.css.ts`: vanilla-extract 스타일 파일은 camelCase로, `.css.ts` 확장자를 사용해야 하며, 해당 컴포넌트와 같은 폴더에 배치해야 한다.

**/*.css.ts: vanilla-extract 스타일 파일은 camelCase로, .css.ts 확장자를 사용해야 하며, 해당 컴포넌트와 같은 폴더에 배치해야 한다.

📄 Source: CodeRabbit Inference Engine (.cursor/rules/nextjs-folder-structure.mdc)

List of files the instruction was applied to:

  • src/components/ui/BottomSheet/BottomSheet.css.ts
🧠 Learnings (1)
src/components/ui/BottomSheet/BottomSheet.css.ts (2)
Learnt from: CR
PR: YAPP-Github/26th-Web-Team-1-FE#0
File: .cursor/rules/nextjs-folder-structure.mdc:0-0
Timestamp: 2025-06-30T08:25:30.684Z
Learning: Applies to **/*.css.ts : vanilla-extract 스타일 파일은 camelCase로, `.css.ts` 확장자를 사용해야 하며, 해당 컴포넌트와 같은 폴더에 배치해야 한다.
Learnt from: CR
PR: YAPP-Github/26th-Web-Team-1-FE#0
File: .cursor/rules/nextjs-folder-structure.mdc:0-0
Timestamp: 2025-06-30T08:25:30.684Z
Learning: 스타일 근접성: vanilla-extract 스타일 파일은 해당 컴포넌트와 같은 폴더에 배치해야 한다.
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (8)
package.json (1)

28-28: vaul 패키지 최신 버전 확인됨, 보안 감사 추가 진행 필요

vaul 버전 ^1.1.2는 NPM의 최신(1.1.2)과 일치합니다. 다만 보안 취약점 검사를 위해선 lockfile이 필요하므로, 아래 절차를 따라 추가 검증을 진행해주세요.

  • package-lock.json 생성
    npm i --package-lock-only
  • 보안 감사 실행
    npm audit --audit-level moderate
  • 감사 결과 이상 여부 확인 후 병합 여부 결정
src/components/ui/BottomSheet/index.ts (1)

1-1: 올바른 barrel export 패턴 사용

BottomSheet 컴포넌트의 re-export가 표준 패턴에 따라 올바르게 구현되었습니다.

src/components/ui/BottomSheet/BottomSheet.tsx (2)

29-33: 접근성 속성 적절히 구현됨

aria-modal과 role="dialog" 속성이 올바르게 적용되어 접근성이 잘 고려되었습니다.


6-13: Props 타입 정의가 명확함

BottomSheetProps 타입이 명확하고 적절하게 정의되었습니다. 모든 필수/선택 속성이 올바르게 표현되었습니다.

src/components/ui/BottomSheet/BottomSheet.css.ts (1)

1-4: 파일명 및 구조 규칙 준수

vanilla-extract 스타일 파일이 코딩 가이드라인에 따라 camelCase와 .css.ts 확장자를 사용하며 컴포넌트와 같은 폴더에 올바르게 배치되었습니다.

src/components/ui/BottomSheet/BottomSheet.stories.tsx (3)

23-45: BottomSheetWrapper 구현이 적절함

상태 관리를 위한 래퍼 컴포넌트가 Storybook 패턴에 따라 올바르게 구현되었습니다. useState를 사용한 상태 관리와 props 전달이 적절합니다.


7-18: Storybook 메타데이터 설정이 적절함

컴포넌트의 Storybook 설정이 올바르게 구성되었습니다. argTypes 설정으로 적절한 컨트롤을 제공하고 있습니다.


72-77: viewMode 기반 조건부 렌더링이 적절함

Docs 모드에서는 닫힌 상태로, Canvas 모드에서는 열린 상태로 표시하는 로직이 사용자 경험을 고려하여 잘 구현되었습니다.

@github-actions
Copy link

@github-actions
Copy link

github-actions bot commented Jul 1, 2025

Copy link
Member

@Seojunhwan Seojunhwan left a comment

Choose a reason for hiding this comment

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

디자인이 바뀌지 않는다! 라고 하면 지금 구현을 그대로 사용해도 좋을 것 같아요!

만약 디자인이 변경될 수도 있고, 여러 상황에 대처해야 한다면 compound 패턴으로 만들어봐도 좋을 것 같아요! ex) vaul 컴포넌트 인터페이스처럼요!

@github-actions
Copy link

github-actions bot commented Jul 3, 2025

@Seojunhwan
Copy link
Member

@wkdtnqls0506 수빈님, 고생하셨습니다! conflict만 처리해주실 수 있나요?!

  1. git fetch
  2. git rebase origin/main
  3. lock file 제외하고 conflict 해결, git checkout --theirs pnpm-lock.yaml
  4. pnpm i
  5. commit 후 force push!

Seojunhwan
Seojunhwan previously approved these changes Jul 3, 2025
@wkdtnqls0506 wkdtnqls0506 merged commit 79a76cc into main Jul 3, 2025
6 checks passed
@wkdtnqls0506 wkdtnqls0506 deleted the feature/PRODUCT-112 branch July 3, 2025 16:44
@coderabbitai coderabbitai bot mentioned this pull request Jul 7, 2025
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ feature 새로운 기능 추가

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[PRODUCT-112] BottomSheet 컴포넌트 생성

2 participants