Skip to content

feat: Dialog 컴포넌트 구현#20

Merged
ccconac merged 11 commits intodevfrom
feat/14-dialog-component
Dec 29, 2025
Merged

feat: Dialog 컴포넌트 구현#20
ccconac merged 11 commits intodevfrom
feat/14-dialog-component

Conversation

@ccconac
Copy link
Copy Markdown
Member

@ccconac ccconac commented Dec 29, 2025

✅ 체크리스트

  • IconLogo 컴포넌트 size prop 추가 (md, xl)
  • icon asset 2종 추가 (close, triangle-alert)
  • Dialog 컴포넌트 구현

📝 작업 상세 내용

radix-ui를 활용해 Dialog 컴포넌트 구현을 완료했습니다. 현재 코드의 가독성이 좋지 않아 구조가 변경될 가능성이 있습니다. components/Dialog는 common 컴포넌트로 확장성 있게 구현하고, components/Navigation/_components/Dialog에서는 특정 도메인에 종속된 Dialog들을 추가 구현 했습니다. 딱히 좋은 방법은 아닌 것 같아서 이것도 추후 수정될 수 있습니다.

아래와 같이 사용 가능합니다.

<Dialog.Login trigger={AddPromptButton()} />
<Dialog.Login trigger={LoginButton()} />

<Dialog.Withdraw trigger={trigger} />

🔎 후속 작업 (선택 사항)

아래 작업들은 mvp 구현을 위한 태스크는 아니라 후속 작업으로 미뤄 두었습니다.

  • Dialog(common)컴포넌트에 Checkbox 컴포넌트 추가가 필요합니다.
  • WithdrawDialog에 Callout 컴포넌트 추가가 필요합니다.
  • Button 컴포넌트 확장이 필요합니다. (feedback, secondary)
  • NavigationBar: 로그인 여부에 따른 분기가 필요합니다.
  • Login/WithdrawDialog: 각 버튼에 해당하는 액션(이벤트) 추가가 필요합니다.

📸 스크린샷 (선택 사항)

스크린샷 2025-12-29 오후 10 02 12 스크린샷 2025-12-29 오후 10 02 35

✅ 셀프 체크리스트

  • 브랜치 확인하기
  • 불필요한 코드가 들어가지 않았는지 재확인하기
  • issue 닫기
  • reiewers, assignees, Lables 등록 확인하기

이슈 번호: #14

Summary by CodeRabbit

  • 새로운 기능

    • 재사용 가능한 모달 다이얼로그 컴포넌트 추가(기본 다이얼로그 + 로그인/탈퇴 변형)
    • 로고에 크기 옵션(md/xl) 및 아이콘 크기 매핑 추가
    • 탈퇴용 경고 아이콘 컴포넌트 추가
    • 아이콘 집합에 닫기·삼각형 경고 아이콘 추가
  • 리팩토링

    • 일부 컴포넌트의 모듈/타입 참조 경로 정리 및 API 타입 분리 적용

✏️ Tip: You can customize this high-level summary in your review settings.

@ccconac ccconac self-assigned this Dec 29, 2025
@ccconac ccconac added ✨ FEAT 기능 개발 💄 DESIGN UI 구현 labels Dec 29, 2025
@ccconac ccconac linked an issue Dec 29, 2025 that may be closed by this pull request
1 task
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 29, 2025

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

새로운 Radix 기반 Dialog 컴포넌트를 추가하고 NavigationBar의 일부 버튼을 Dialog 트리거로 교체했습니다. Logo에 사이즈 옵션과 스타일 매핑(iconSizeMap)을 도입했고, 아이콘 맵에 close/triangleAlert를 추가했으며 일부 import 경로를 정정했습니다.

Changes

Cohort / File(s) 변경 요약
Dialog 컴포넌트 신규 추가
src/components/Dialog/Dialog.tsx, src/components/Dialog/Dialog.types.ts
Radix UI 기반 재사용 Dialog 컴포넌트 및 타입 추가(트리거, 아이콘, 제목, 설명, 캡션, primary/secondary 액션 지원).
NavigationBar Dialog 통합
src/components/NavigationBar/NavigationBar.tsx, src/components/NavigationBar/_components/Dialog.tsx, src/components/NavigationBar/_components/WithdrawIcon.tsx
NavigationBar의 버튼들을 Dialog 트리거로 교체. Dialog.Login / Dialog.Withdraw 변형 추가 및 WithdrawIcon 컴포넌트 추가.
Logo 크기 옵션 도입
src/components/Logo/Logo.tsx, src/components/Logo/Logo.types.ts, src/components/Logo/Icon.styles.ts
Logo.Icon에 size prop('md'
아이콘 맵 확장 및 import 경로 정정
src/components/Icon/iconMap.ts, src/components/Card/Card.tsx, src/components/Label/Label.types.ts
iconMapclosetriangleAlert 항목 추가. Card의 Label import 경로 및 Label.types.ts의 IconName 경로 조정.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor User
    participant NavBar as NavigationBar
    participant DialogComp as Dialog
    participant Portal as Portal
    participant Action as ActionButton

    User->>NavBar: 트리거 버튼 클릭
    NavBar->>DialogComp: trigger 전달 / 렌더링
    User->>DialogComp: 트리거 작동 (open)
    DialogComp->>Portal: Portal 생성
    Portal->>DialogComp: Overlay + Content 렌더링
    DialogComp->>DialogComp: 아이콘/제목/설명/액션 렌더

    alt LoginDialog
        DialogComp->>Action: 카카오 로그인 버튼 표시
        User->>Action: 로그인 클릭
        Action-->>User: 로그인 처리
    else WithdrawDialog
        DialogComp->>Action: 취소/탈퇴 버튼 표시
        User->>Action: 선택 (취소/탈퇴)
        Action-->>User: 선택 처리
    end

    User->>DialogComp: Close 클릭
    DialogComp-->>NavBar: 모달 종료
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 주요 변경사항인 Dialog 컴포넌트 구현을 명확하게 요약하고 있습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 032e00f and 4d6abc7.

📒 Files selected for processing (1)
  • src/components/Dialog/Dialog.types.ts

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@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: 2

🧹 Nitpick comments (5)
src/components/NavigationBar/NavigationBar.tsx (1)

7-13: 컴포넌트를 NavigationBar 외부로 이동 고려

AddPromptButtonLoginButton이 NavigationBar 내부에 정의되어 있어 매 렌더링마다 새로 생성됩니다. 성능 최적화를 위해 컴포넌트 외부로 이동하는 것을 권장합니다.

🔎 수정 제안
+const AddPromptButton = () => (
+  <Button icon="addLine" iconSize="md">
+    프롬프트 등록
+  </Button>
+);
+
+const LoginButton = () => <Button variant="solid">로그인</Button>;
+
 const NavigationBar = () => {
-  const AddPromptButton = () => (
-    <Button icon="addLine" iconSize="md">
-      프롬프트 등록
-    </Button>
-  );
-
-  const LoginButton = () => <Button variant="solid">로그인</Button>;
-
   return (
     // ...
   );
 };
src/components/Logo/Icon.styles.ts (1)

1-4: LGTM!

iconSizeMap이 깔끔하게 정의되었습니다. 타입 안전성을 위해 as const를 추가하면 더 좋습니다.

🔎 타입 안전성 향상을 위한 제안
 export const iconSizeMap = {
   md: 'w-8 h-8 rounded-lg',
   xl: 'w-16 h-16 rounded-2xl',
-};
+} as const;
src/components/Dialog/Dialog.tsx (1)

42-42: 불필요한 코드를 제거하세요.

?? undefined는 중복입니다. JSX에서 falsy 값은 자동으로 렌더링되지 않습니다.

🔎 제안된 수정사항
-                {secondaryAction ?? undefined}
+                {secondaryAction}
src/components/NavigationBar/_components/Dialog.tsx (2)

37-50: primaryAction과 secondaryAction의 명명이 혼란스러울 수 있습니다.

현재 "취소" 버튼이 primaryAction으로, "탈퇴하기" 버튼이 secondaryAction으로 전달되고 있습니다. 시각적 스타일은 올바르지만(취소는 회색, 탈퇴는 빨강), 의미상으로는 반대로 보일 수 있습니다.

기본 Dialog 컴포넌트가 단순히 순서대로 렌더링하는 것이라면 문제없지만, 향후 primary/secondary에 다른 의미(예: 포커스 순서, 키보드 단축키)가 부여될 경우 혼란을 야기할 수 있습니다.

다음 중 하나를 고려해보세요:

  1. 명명을 leftAction/rightAction 또는 cancelAction/confirmAction으로 변경
  2. 현재 방식을 유지하되 주석으로 의도를 명확히 표시
  3. Dialog 컴포넌트에서 actions 배열을 받아 순서를 명시적으로 제어

29-29: TODO 주석이 명확합니다.

향후 필요한 개선사항이 잘 문서화되어 있습니다.

Callout이나 Checkbox 컴포넌트 구현이 필요하시면 새 이슈를 생성하도록 도와드릴 수 있습니다. 필요하신가요?

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ceb64be and 0c0d637.

⛔ Files ignored due to path filters (5)
  • src/assets/icons/close.svg is excluded by !**/*.svg
  • src/assets/icons/triangle-alert.svg is excluded by !**/*.svg
  • src/components/Icon/generated/Close.tsx is excluded by !**/generated/**
  • src/components/Icon/generated/TriangleAlert.tsx is excluded by !**/generated/**
  • src/components/Icon/generated/index.tsx is excluded by !**/generated/**
📒 Files selected for processing (13)
  • src/components/Card/Card.tsx
  • src/components/Dialog/Dialog.tsx
  • src/components/Dialog/Dialog.types.ts
  • src/components/Icon/iconMap.ts
  • src/components/Label/Label.styles.ts
  • src/components/Label/Label.tsx
  • src/components/Label/Label.types.ts
  • src/components/Logo/Icon.styles.ts
  • src/components/Logo/Logo.tsx
  • src/components/Logo/Logo.types.ts
  • src/components/NavigationBar/NavigationBar.tsx
  • src/components/NavigationBar/_components/Dialog.tsx
  • src/components/NavigationBar/_components/WithdrawIcon.tsx
🧰 Additional context used
🧬 Code graph analysis (6)
src/components/Icon/iconMap.ts (1)
src/components/Icon/Icon.tsx (1)
  • Icon (4-18)
src/components/NavigationBar/NavigationBar.tsx (2)
src/components/Logo/Logo.tsx (1)
  • Logo (34-37)
src/components/Dialog/Dialog.tsx (1)
  • Dialog (5-51)
src/components/NavigationBar/_components/Dialog.tsx (2)
src/components/Dialog/Dialog.types.ts (1)
  • DialogProps (12-12)
src/components/Logo/Logo.tsx (1)
  • Logo (34-37)
src/components/Logo/Logo.tsx (3)
src/components/Logo/Logo.types.ts (2)
  • IconLogoProps (3-5)
  • BasicLogoProps (7-7)
src/components/Logo/Icon.styles.ts (1)
  • iconSizeMap (1-4)
src/components/Icon/Icon.tsx (1)
  • Icon (4-18)
src/components/Dialog/Dialog.tsx (2)
src/components/Dialog/Dialog.types.ts (1)
  • DialogProps (12-12)
src/components/Icon/Icon.tsx (1)
  • Icon (4-18)
src/components/NavigationBar/_components/WithdrawIcon.tsx (1)
src/components/Icon/Icon.tsx (1)
  • Icon (4-18)
🔇 Additional comments (11)
src/components/Card/Card.tsx (1)

1-1: LGTM!

Import 경로가 디렉토리 구조에 맞게 올바르게 수정되었습니다.

src/components/Label/Label.types.ts (1)

2-2: LGTM!

상대 경로가 올바르게 수정되었습니다.

src/components/Icon/iconMap.ts (1)

19-23: LGTM!

Dialog 닫기 버튼(close)과 탈퇴 아이콘(triangleAlert)에 필요한 아이콘이 iconMap에 올바르게 추가되었습니다.

src/components/NavigationBar/NavigationBar.tsx (1)

21-22: "프롬프트 등록" 버튼도 Login Dialog를 표시하는 것이 의도된 동작인지 확인 필요

현재 AddPromptButtonLoginButton 모두 Dialog.Login을 사용하고 있습니다. TODO 주석에서 언급된 것처럼 향후 로그인 여부에 따른 분기가 필요하다면, 비로그인 상태에서 프롬프트 등록 시 로그인 유도는 합리적인 UX입니다. 다만, 로그인된 사용자에게는 다른 다이얼로그(프롬프트 작성)가 표시되어야 할 것으로 보입니다.

src/components/Logo/Logo.types.ts (1)

3-7: LGTM!

Logo 컴포넌트 변형별로 타입이 명확하게 분리되었습니다. size prop이 iconSizeMap의 키와 일치하며, HTMLAttributes 확장으로 네이티브 HTML 속성도 지원됩니다.

src/components/NavigationBar/_components/WithdrawIcon.tsx (1)

5-7: stroke/fill props로 SVG 속성 오버라이드 작동 중 - 추가 수정 불필요

The stroke and fill props are correctly passed through the Icon component to the SVG element and properly override the inline SVG attributes. However, the suggestion to use Tailwind stroke utilities (stroke-red-600) would not work in this context because inline SVG attributes take precedence over CSS classes.

The current implementation is correct. For improved consistency with the design system, consider using the Icon component's color prop instead: <Icon name="triangleAlert" size="xl" color="#e7000b" />, which leverages the SVG's currentColor values.

Likely an incorrect or invalid review comment.

src/components/Dialog/Dialog.tsx (2)

5-51: 전체적인 Dialog 구현이 잘 되어 있습니다.

Radix UI 기반의 접근성을 고려한 Dialog 구조, Portal을 통한 올바른 렌더링, 그리고 확장 가능한 컴포넌트 설계가 잘 구현되어 있습니다.


1-1: 코드가 올바릅니다. 추가 조치가 필요하지 않습니다.

radix-ui는 Radix Primitives의 공식 메타 패키지이며, import { Dialog as DialogPrimitive } from 'radix-ui';는 유효한 import 문법입니다. Dialog를 가져오는 두 가지 공식 방식이 모두 지원됩니다:

  • 메타 패키지 사용 (현재 코드): import { Dialog } from "radix-ui";
  • 개별 패키지 사용: import * as DialogPrimitive from "@radix-ui/react-dialog";

Likely an incorrect or invalid review comment.

src/components/NavigationBar/_components/Dialog.tsx (1)

8-25: LoginDialog 구현이 깔끔합니다.

카카오 로그인을 위한 적절한 색상과 레이아웃이 잘 구현되어 있습니다. 캡션을 통한 약관 동의 안내도 UX 관점에서 좋습니다.

src/components/Logo/Logo.tsx (2)

3-4: import 구조가 명확합니다.

타입과 스타일을 분리하여 import하는 구조가 좋습니다.


6-14: size 속성 구현이 정확하고 완벽합니다.

기본값 설정, 타입 안전성, 그리고 iconSizeMap을 통한 스타일링이 깔끔하게 구현되어 있습니다. Icon 컴포넌트의 sizeMap에는 'md'(20px)와 'xl'(32px)이 모두 포함되어 있으며, Logo 컴포넌트에서 size 속성을 올바르게 전달하고 있습니다.

<button
className="absolute top-4 right-4 p-2 text-gray-400 hover:text-gray-600 rounded-lg hover:bg-gray-100 transition-colors"
aria-label="닫기">
<Icon name="close" size="md" aria-hidden />
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

aria-hidden 속성 문법을 수정하세요.

React에서 boolean 속성은 명시적으로 값을 지정해야 합니다.

🔎 제안된 수정사항
-                <Icon name="close" size="md" aria-hidden />
+                <Icon name="close" size="md" aria-hidden="true" />
📝 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
<Icon name="close" size="md" aria-hidden />
<Icon name="close" size="md" aria-hidden="true" />
🤖 Prompt for AI Agents
In src/components/Dialog/Dialog.tsx around line 26, the JSX uses the boolean
attribute aria-hidden without an explicit value; update the attribute to use
explicit boolean syntax (e.g., aria-hidden={true} or aria-hidden={false} as
appropriate) so React treats it as a boolean prop, and ensure the chosen value
reflects whether the icon should be exposed to assistive technologies.

Comment thread src/components/Dialog/Dialog.types.ts
@ccconac ccconac merged commit 7b0bcb0 into dev Dec 29, 2025
Copy link
Copy Markdown

@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: 0

♻️ Duplicate comments (1)
src/components/Dialog/Dialog.tsx (1)

27-27: aria-hidden 속성 문법을 수정하세요.

이 문제는 이전 리뷰에서 이미 지적되었습니다. React에서 boolean 속성은 명시적으로 값을 지정해야 합니다.

🔎 제안된 수정사항
-                <Icon name="close" size="md" aria-hidden />
+                <Icon name="close" size="md" aria-hidden="true" />
🧹 Nitpick comments (3)
src/components/Dialog/Dialog.tsx (3)

5-5: TODO 해결을 도와드릴 수 있습니다.

액션 버튼의 네이밍에 대한 고민이 남아있네요. 일반적인 대안으로는 confirmAction/cancelAction, onConfirm/onCancel, 또는 submitButton/cancelButton 등이 있습니다.

네이밍 개선안 코드를 생성하거나 이 작업을 추적할 이슈를 열어드릴까요?


21-22: DialogContent 래핑 구조를 재검토하세요.

DialogPrimitive.Content를 별도의 div로 감싸는 것은 Radix UI의 표준 패턴이 아닙니다. 일반적으로 DialogContent는 Portal의 직접 자식으로 배치되며, 자체적으로 포지셔닝을 처리합니다. 이 추가 래퍼는 Radix의 내장 포지셔닝, 포커스 트래핑 또는 접근성 동작을 방해할 수 있습니다.

센터링이 필요하다면 DialogContent의 className에 직접 적용하는 것을 권장합니다.

🔎 권장 구조 수정안
       <DialogPrimitive.Portal>
         <DialogPrimitive.Overlay className="fixed inset-0 bg-black/50 z-50" />
-        <div className="fixed inset-0 flex items-center justify-center z-50 p-4">
-          <DialogPrimitive.Content className="bg-white rounded-xl max-w-md w-full p-8 relative focus:outline-none">
+          <DialogPrimitive.Content className="fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 bg-white rounded-xl max-w-md w-full p-8 relative focus:outline-none z-50">
             <DialogPrimitive.Close asChild>
               <button
                 className="absolute top-4 right-4 p-2 text-gray-400 hover:text-gray-600 rounded-lg hover:bg-gray-100 transition-colors"
                 aria-label="닫기">
                 <Icon name="close" size="md" aria-hidden />
               </button>
             </DialogPrimitive.Close>
             <div className="flex flex-col gap-6">
               {/* ... content ... */}
             </div>
           </DialogPrimitive.Content>
-        </div>
       </DialogPrimitive.Portal>

41-44: 모바일 환경에서 버튼 레이아웃을 고려하세요.

현재 버튼들이 flex gap-3로 가로 배치되어 있습니다. 좁은 화면에서는 버튼이 잘리거나 너무 작아질 수 있으니, 반응형 처리(flex-col sm:flex-row 등)를 고려해보세요.

🔎 반응형 레이아웃 예시
-              <div className="flex gap-3">
+              <div className="flex flex-col sm:flex-row gap-3">
                 {primaryAction}
                 {secondaryAction}
               </div>
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0c0d637 and 032e00f.

📒 Files selected for processing (2)
  • src/components/Dialog/Dialog.tsx
  • src/components/NavigationBar/NavigationBar.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/NavigationBar/NavigationBar.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
src/components/Dialog/Dialog.tsx (2)
src/components/Dialog/Dialog.types.ts (1)
  • DialogProps (12-12)
src/components/Icon/Icon.tsx (1)
  • Icon (4-18)
🔇 Additional comments (2)
src/components/Dialog/Dialog.tsx (2)

33-38: 의미론적 Dialog 구조가 올바르게 구현되었습니다.

DialogPrimitive.Title과 DialogPrimitive.Description을 적절히 사용하여 스크린 리더 사용자에게 올바른 컨텍스트를 제공하고 있습니다. 닫기 버튼의 aria-label도 적절합니다.


1-1: import 경로는 프로젝트의 실제 dependencies와 일치합니다.

package.json에서 "radix-ui": "^1.4.3"이 정의되어 있으며, 현재 import 문 from 'radix-ui'는 이와 정확히 일치합니다. 이 프로젝트는 표준 @radix-ui/react-* 패키지 대신 "radix-ui" 패키지를 사용하고 있으므로 현재 import 경로는 올바르고 변경할 필요가 없습니다.

Likely an incorrect or invalid review comment.

@ccconac ccconac deleted the feat/14-dialog-component branch December 29, 2025 13:17
@coderabbitai coderabbitai Bot mentioned this pull request Dec 31, 2025
8 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💄 DESIGN UI 구현 ✨ FEAT 기능 개발

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Dialog 컴포넌트 구현

1 participant