Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"build-storybook": "storybook build"
},
"dependencies": {
"@radix-ui/react-dialog": "^1.1.14",
Copy link

@coderabbitai coderabbitai bot Jul 18, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue

잘못된 패키지 의존성이 추가되었습니다.

파이프라인 실패 로그에 따르면 실제 구현에서는 @radix-ui/react-alert-dialog를 사용하려고 하지만, 여기서는 @radix-ui/react-dialog가 추가되었습니다. PR 목표에서 언급한 대로 알림 모달의 적절한 동작을 위해 @radix-ui/react-alert-dialog를 사용해야 합니다.

다음 diff를 적용하여 올바른 패키지를 추가하세요:

-    "@radix-ui/react-dialog": "^1.1.14",
+    "@radix-ui/react-alert-dialog": "^1.1.14",
📝 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
"@radix-ui/react-dialog": "^1.1.14",
- "@radix-ui/react-dialog": "^1.1.14",
+ "@radix-ui/react-alert-dialog": "^1.1.14",
🤖 Prompt for AI Agents
In package.json at line 20, the dependency "@radix-ui/react-dialog" is
incorrectly added instead of "@radix-ui/react-alert-dialog". Replace
"@radix-ui/react-dialog" with "@radix-ui/react-alert-dialog" to match the actual
implementation and ensure the alert modal functions correctly as intended.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link

Choose a reason for hiding this comment

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

@wkdtnqls0506 Perfect! I can see you've fixed the package dependency issue in commit b7ca0ad. Thank you for quickly applying the correction to use @radix-ui/react-alert-dialog instead of @radix-ui/react-dialog. This ensures the AlertModal component will have the proper alert dialog behavior that prevents closing on overlay clicks, which is essential for alert modals that require user confirmation.


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

"@hookform/resolvers": "^5.1.1",
"@tanstack/react-query": "^5.77.0",
"@tanstack/react-query-devtools": "^5.77.0",
Expand Down
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

59 changes: 59 additions & 0 deletions src/components/ui/AlertModal/AlertModal.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { style } from "@vanilla-extract/css";

import { radius, semantic, typography } from "@/styles";
import { zIndex } from "@/styles/zIndex.css";

export const overlay = style({
position: "fixed",
inset: 0,
backgroundColor: semantic.background.dim,
zIndex: zIndex.overlay,
});

export const content = style({
maxHeight: "80vh",
display: "flex",
flexDirection: "column",
position: "fixed",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: "min(30rem, 90vw)",
background: semantic.background.white,
borderRadius: radius[120],
zIndex: zIndex.modal,
});

export const innerContent = style({
overflowY: "auto",
padding: "4.8rem 1.6rem",
display: "flex",
flexDirection: "column",
alignItems: "center",
});

export const title = style({
...typography.title3Sb,
color: semantic.text.normal,
});

export const description = style({
...typography.body2Rg,
color: semantic.text.alternative,
marginTop: "0.8rem",
width: "100%",
textAlign: "center",
});

export const footer = style({
width: "100%",
display: "flex",
});

export const cancelButton = style({
flex: 1,
});

export const confirmButton = style({
flex: 1,
});
119 changes: 119 additions & 0 deletions src/components/ui/AlertModal/AlertModal.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import * as AlertDialog from "@radix-ui/react-alert-dialog";
Copy link

@coderabbitai coderabbitai bot Jul 18, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue

잘못된 패키지 import로 인한 빌드 실패

@radix-ui/react-alert-dialog 패키지를 import하고 있지만, 파이프라인 실패 로그를 보면 해당 패키지가 설치되지 않은 것으로 보입니다. AI 요약에 따르면 package.json에는 @radix-ui/react-dialog만 추가되어 있습니다.

아래 diff를 적용하여 올바른 패키지를 import하거나, 올바른 패키지를 설치하세요:

-import * as AlertDialog from "@radix-ui/react-alert-dialog";
+import * as AlertDialog from "@radix-ui/react-dialog";

또는 @radix-ui/react-alert-dialog 패키지를 설치하세요 (PR 목표에 따르면 이 패키지 사용이 권장됨).

📝 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
import * as AlertDialog from "@radix-ui/react-alert-dialog";
import * as AlertDialog from "@radix-ui/react-dialog";
🧰 Tools
🪛 GitHub Actions: Storybook Chromatic Deployment

[error] 1-1: Build failed: Module not found error - Can't resolve '@radix-ui/react-alert-dialog' in './src/components/ui/AlertModal'. This caused the Storybook build to fail with exit code 1.

🤖 Prompt for AI Agents
In src/components/ui/AlertModal/AlertModal.stories.tsx at line 1, the import
statement uses the package @radix-ui/react-alert-dialog which is not installed
according to the build failure logs and package.json. To fix this, either change
the import to use the installed package @radix-ui/react-dialog or install the
@radix-ui/react-alert-dialog package as intended by the PR goals. Ensure the
import matches the installed package to resolve the build failure.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the specific commit to see what changes were made
git show --name-only b7ca0ad214e22997d1c9920f76e5d008525a4699

# Show the actual changes in the commit
git show b7ca0ad214e22997d1c9920f76e5d008525a4699

Length of output: 3673


@wkdtnqls0506 Perfect! 🎉 You've installed the @radix-ui/react-alert-dialog package, which resolves the build failure. This is the correct approach as it aligns with the PR objectives to use the proper alert dialog package that prevents closing on overlay click, providing the expected UX behavior for alert modals.

The build should now pass successfully!

(∩。・o・。)∩ ♪


🧬 Code Graph Analysis Results

Relevant snippet from src/components/ui/AlertModal/AlertModal.tsx (lines 50-75)

export const AlertModal = ({
  title,
  trigger,
  content,
  footer,
}: AlertModalProps) => {
  return (
    <AlertDialog.Root>
      {trigger && <AlertDialog.Trigger asChild>{trigger}</AlertDialog.Trigger>}
      <AlertDialog.Portal>
        <AlertDialog.Overlay className={styles.overlay} />
        <AlertDialog.Content className={styles.content}>
          <section className={styles.innerContent}>
            {title && (
              <AlertDialog.Title className={styles.title}>
                {title}
              </AlertDialog.Title>
            )}
            {content && <div className={styles.description}>{content}</div>}
          </section>
          {footer && <div className={styles.footer}>{footer}</div>}
        </AlertDialog.Content>
      </AlertDialog.Portal>
    </AlertDialog.Root>
  );
};

This snippet defines the AlertModal component used in the story file. It accepts props title, trigger, content, and footer and renders a modal dialog using Radix UI's AlertDialog primitives. The modal includes conditional rendering of the title, content, and footer sections, and uses styles imported from AlertModal.css.


Possibly relevant snippet from src/components/ui/AlertModal/index.ts (line 1)

AlertModal

This likely exports the AlertModal component, which is imported and used in the story file.


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

import type { Meta, StoryObj } from "@storybook/nextjs";

import { Button } from "../Button";
import { AlertModal } from "./AlertModal";
import * as styles from "./AlertModal.css";

const meta: Meta<typeof AlertModal> = {
title: "Components/AlertModal",
component: AlertModal,
tags: ["autodocs"],
argTypes: {
title: {
control: "text",
description: "모달의 제목",
},
trigger: {
control: false,
description: "모달을 열기 위한 트리거(버튼 등, ReactNode)",
},
content: {
control: false,
description: "본문(설명 등, ReactNode)",
},
footer: {
control: false,
description:
"하단 푸터(버튼 영역 등, ReactNode). Radix의 <AlertDialog.Cancel asChild> 또는 <AlertDialog.Action asChild>를 조합하여 사용.",
},
},
parameters: {
layout: "centered",
docs: {
description: {
component:
"AlertModal은 사용자에게 확인/취소 액션을 요청할 때 사용하는 모달입니다. title, trigger, content, footer props를 지원합니다.",
},
},
},
};

export default meta;
type Story = StoryObj<typeof AlertModal>;

export const Default: Story = {
render: args => <AlertModal {...args} />,
args: {
title: "정말 삭제하시겠어요?",
trigger: <Button>모달 열기</Button>,
content: <div>삭제하면 복구할 수 없습니다.</div>,
footer: (
<>
<AlertDialog.Cancel asChild>
<Button
variant='assistive'
className={styles.cancelButton}
style={{ borderRadius: "0 0 0 1.2rem" }}
>
취소
</Button>
</AlertDialog.Cancel>
<AlertDialog.Action asChild>
<Button
variant='primary'
className={styles.confirmButton}
style={{ borderRadius: "0 0 1.2rem 0" }}
>
삭제
</Button>
</AlertDialog.Action>
</>
),
},
parameters: {
docs: {
description: {
story:
"기본 AlertModal. 타이틀과 설명, 확인/취소 버튼을 모두 포함합니다.",
},
},
},
};

export const NoDescription: Story = {
render: args => <AlertModal {...args} />,
args: {
title: "약관을 동의하시겠습니까?",
trigger: <Button>모달 열기</Button>,
footer: (
<>
<AlertDialog.Cancel asChild>
<Button
variant='assistive'
className={styles.cancelButton}
style={{ borderRadius: "0 0 0 1.2rem" }}
>
취소
</Button>
</AlertDialog.Cancel>
<AlertDialog.Action asChild>
<Button
variant='primary'
className={styles.confirmButton}
style={{ borderRadius: "0 0 1.2rem 0" }}
>
동의
</Button>
</AlertDialog.Action>
</>
),
},
parameters: {
docs: {
description: {
story: "description 없이 타이틀과 버튼만 표시되는 AlertModal입니다.",
},
},
},
};
75 changes: 75 additions & 0 deletions src/components/ui/AlertModal/AlertModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import * as AlertDialog from "@radix-ui/react-alert-dialog";
Copy link

@coderabbitai coderabbitai bot Jul 18, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue

잘못된 패키지 import로 인한 빌드 실패

스토리 파일과 동일한 문제로, @radix-ui/react-alert-dialog 패키지를 import하고 있지만 해당 패키지가 설치되지 않았습니다.

아래 diff를 적용하여 올바른 패키지를 import하거나, 올바른 패키지를 설치하세요:

-import * as AlertDialog from "@radix-ui/react-alert-dialog";
+import * as AlertDialog from "@radix-ui/react-dialog";

또는 @radix-ui/react-alert-dialog 패키지를 설치하세요.

🧰 Tools
🪛 GitHub Actions: Storybook Chromatic Deployment

[error] 1-1: Build failed: Module not found error - Can't resolve '@radix-ui/react-alert-dialog' in './src/components/ui/AlertModal'. This caused the Storybook build to fail with exit code 1.

🤖 Prompt for AI Agents
In src/components/ui/AlertModal/AlertModal.tsx at line 1, the import statement
uses the package @radix-ui/react-alert-dialog which is not installed, causing
build failure. To fix this, either change the import to use the correct
installed package that provides AlertDialog functionality or install the missing
@radix-ui/react-alert-dialog package via your package manager. Ensure the import
matches the installed dependency to resolve the build error.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check what changes were made in the referenced commit
git show b7ca0ad214e22997d1c9920f76e5d008525a4699 --name-only

# Show the actual changes in the commit
git show b7ca0ad214e22997d1c9920f76e5d008525a4699

# Check if the package was added to package.json
git show b7ca0ad214e22997d1c9920f76e5d008525a4699 -- package.json

Length of output: 4423


@wkdtnqls0506 완벽하게 해결되었습니다! 🎉

커밋을 확인해보니 누락된 @radix-ui/react-alert-dialog 패키지를 정상적으로 설치하셨네요. 이제 빌드 실패 문제가 해결되고, AlertModal 컴포넌트가 의도한 대로 작동할 것입니다.

특히 @radix-ui/react-alert-dialog를 사용하는 것이 올바른 선택입니다 - 오버레이 클릭 시 모달이 닫히지 않는 alert dialog 특성에 맞는 패키지이기 때문입니다.

(\ /)
( .. )
o
(")(")


🧬 Code Graph Analysis Results

Relevant snippets from src/components/ui/AlertModal/index.ts (line 1)

AlertModal
  • This likely re-exports the AlertModal component from AlertModal.tsx.

Relevant snippets from src/components/ui/AlertModal/AlertModal.css.ts

At lines 13-25:

export const content = style({
  maxHeight: "80vh",
  display: "flex",
  flexDirection: "column",
  position: "fixed",
  top: "50%",
  left: "50%",
  transform: "translate(-50%, -50%)",
  width: "min(30rem, 90vw)",
  background: semantic.background.white,
  borderRadius: radius[120],
  zIndex: zIndex.modal,
});
  • Defines the CSS styles for the modal content container, including positioning, size, background, border radius, and z-index.

At lines 35-38:

export const title = style({
  ...typography.title3Sb,
  color: semantic.text.normal,
});
  • Defines the CSS styles for the modal title, applying typography styles and text color.

At lines 48-51:

export const footer = style({
  width: "100%",
  display: "flex",
});
  • Defines the CSS styles for the modal footer container, setting full width and flex display.

These snippets provide the styling context for the AlertModal component's structure and elements.


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

import { type ReactNode } from "react";

import * as styles from "./AlertModal.css";

export type AlertModalProps = {
/** 모달의 제목 */
title?: string;

/** 모달을 열기 위한 트리거(버튼 등, 선택) */
trigger?: ReactNode;

/** 본문(설명 등, ReactNode로 자유롭게 구성) */
content?: ReactNode;

/**
* 하단 푸터(버튼 영역 등, ReactNode로 자유롭게 구성)
* Radix의 <AlertDialog.Cancel asChild> 또는 <AlertDialog.Action asChild>를 조합하여 사용 가능
* 예시:
* <>
* <AlertDialog.Cancel asChild>
* <Button>취소</Button>
* </AlertDialog.Cancel>
* <AlertDialog.Action asChild>
* <Button>확인</Button>
* </AlertDialog.Action>
* </>
*/
footer?: ReactNode;
};

/**
* AlertModal 컴포넌트
*
* @example
* ```tsx
* <AlertModal
* title="정말 삭제하시겠어요?"
* trigger={<Button>모달 열기</Button>}
* content={<div>삭제하면 복구할 수 없습니다.</div>}
* footer={
* <>
* <Button variant="assistive">취소</Button>
* <Button variant="primary">삭제</Button>
* </>
* }
* />
* ```
Comment on lines +35 to +48
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

JSDoc 예제 코드에서 AlertDialog 래퍼 사용 누락

JSDoc 예제에서 footer 버튼들이 AlertDialog.CancelAlertDialog.Action으로 래핑되지 않았습니다. 이는 실제 사용 시 혼란을 야기할 수 있습니다.

예제 코드를 다음과 같이 수정하세요:

 * footer={
 *   <>
-*     <Button variant="assistive">취소</Button>
-*     <Button variant="primary">삭제</Button>
+*     <AlertDialog.Cancel asChild>
+*       <Button variant="assistive">취소</Button>
+*     </AlertDialog.Cancel>
+*     <AlertDialog.Action asChild>
+*       <Button variant="primary">삭제</Button>
+*     </AlertDialog.Action>
 *   </>
 * }
📝 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
* @example
* ```tsx
* <AlertModal
* title="정말 삭제하시겠어요?"
* trigger={<Button>모달 열기</Button>}
* content={<div>삭제하면 복구할 수 없습니다.</div>}
* footer={
* <>
* <Button variant="assistive">취소</Button>
* <Button variant="primary">삭제</Button>
* </>
* }
* />
* ```
* @example
*
🤖 Prompt for AI Agents
In src/components/ui/AlertModal/AlertModal.tsx between lines 35 and 48, the
JSDoc example code for AlertModal is missing the wrapping of footer buttons with
AlertDialog.Cancel and AlertDialog.Action components. To fix this, update the
example so that the cancel button is wrapped with AlertDialog.Cancel and the
delete button is wrapped with AlertDialog.Action, reflecting the actual usage
pattern and preventing confusion.

*/
export const AlertModal = ({
title,
trigger,
content,
footer,
}: AlertModalProps) => {
return (
<AlertDialog.Root>
{trigger && <AlertDialog.Trigger asChild>{trigger}</AlertDialog.Trigger>}
<AlertDialog.Portal>
<AlertDialog.Overlay className={styles.overlay} />
<AlertDialog.Content className={styles.content}>
<section className={styles.innerContent}>
{title && (
<AlertDialog.Title className={styles.title}>
{title}
</AlertDialog.Title>
)}
{content && <div className={styles.description}>{content}</div>}
</section>
{footer && <div className={styles.footer}>{footer}</div>}
</AlertDialog.Content>
</AlertDialog.Portal>
</AlertDialog.Root>
);
};
1 change: 1 addition & 0 deletions src/components/ui/AlertModal/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { AlertModal } from "./AlertModal";
3 changes: 2 additions & 1 deletion src/components/ui/GNB/GNB.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { style } from "@vanilla-extract/css";
import { recipe } from "@vanilla-extract/recipes";

import { semantic, typography } from "@/styles";
import { zIndex } from "@/styles/zIndex.css";

export const wrapper = recipe({
base: {
Expand All @@ -12,7 +13,7 @@ export const wrapper = recipe({
width: "100%",
height: "5.6rem",
padding: "1.4rem 2rem",
zIndex: 999,
zIndex: zIndex.gnb,
},
variants: {
background: {
Expand Down
4 changes: 4 additions & 0 deletions src/styles/reset.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ globalStyle("html", {
fontSize: "62.5%",
});

globalStyle("html, body", {
height: "100%",
});

globalStyle(
"html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video",
{
Expand Down
9 changes: 9 additions & 0 deletions src/styles/zIndex.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { createGlobalTheme } from "@vanilla-extract/css";

export const zIndex = createGlobalTheme(":root", {
base: "0",
gnb: "100",
overlay: "900",
modal: "1000",
toast: "1100",
});
Loading