diff --git a/app/(tabs)/[teamId]/_layout.tsx b/app/(tabs)/[teamId]/_layout.tsx
deleted file mode 100644
index e69de29..0000000
diff --git a/app/(tabs)/[teamId]/calendar.tsx b/app/(tabs)/[teamId]/calendar.tsx
deleted file mode 100644
index 40f354a..0000000
--- a/app/(tabs)/[teamId]/calendar.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import { View } from "react-native";
-
-interface CalendarProps {}
-
-const Calendar = ({}: CalendarProps) => {
- return ;
-};
-
-export default Calendar;
diff --git a/app/(tabs)/[teamId]/calendarModal.tsx b/app/(tabs)/[teamId]/calendarModal.tsx
deleted file mode 100644
index 427fa9f..0000000
--- a/app/(tabs)/[teamId]/calendarModal.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import { View } from "react-native";
-
-interface CalendarModalProps {}
-
-const CalendarModal = ({}: CalendarModalProps) => {
- return ;
-};
-
-export default CalendarModal;
diff --git a/app/(tabs)/[teamId]/index.tsx b/app/(tabs)/[teamId]/index.tsx
deleted file mode 100644
index e69de29..0000000
diff --git a/app/(tabs)/[teamId]/schedule.tsx b/app/(tabs)/[teamId]/schedule.tsx
deleted file mode 100644
index bb8d03e..0000000
--- a/app/(tabs)/[teamId]/schedule.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import { View } from "react-native";
-
-interface ScheduleProps {}
-
-const Schedule = ({}: ScheduleProps) => {
- return ;
-};
-
-export default Schedule;
diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx
index e69de29..e2cdab2 100644
--- a/app/(tabs)/_layout.tsx
+++ b/app/(tabs)/_layout.tsx
@@ -0,0 +1,43 @@
+import MainIcon from "@/assets/icons/main";
+import MyPageIcon from "@/assets/icons/mypage";
+import PersonalIcon from "@/assets/icons/personal";
+import { globalGray50, globalGreen300 } from "@/shared/ui";
+import { Tabs } from "expo-router";
+
+export default function TabsLayout() {
+ return (
+
+ ,
+ }}
+ />
+ ,
+ }}
+ />
+ ,
+ }}
+ />
+
+ );
+}
diff --git a/app/(tabs)/home/_layout.tsx b/app/(tabs)/home/_layout.tsx
new file mode 100644
index 0000000..161589e
--- /dev/null
+++ b/app/(tabs)/home/_layout.tsx
@@ -0,0 +1,16 @@
+import { globalGray50 } from "@/shared/ui";
+import { Stack } from "expo-router";
+
+export default function HomeLayout() {
+ return (
+
+
+
+ );
+}
diff --git a/app/(tabs)/home/index.tsx b/app/(tabs)/home/index.tsx
new file mode 100644
index 0000000..c9fc90f
--- /dev/null
+++ b/app/(tabs)/home/index.tsx
@@ -0,0 +1,15 @@
+import { StyleSheet, Text, View } from "react-native";
+
+interface GroupScreenProps {}
+
+const GroupScreen = ({}: GroupScreenProps) => {
+ return (
+
+ GroupPage
+
+ );
+};
+
+const styles = StyleSheet.create({});
+
+export default GroupScreen;
diff --git a/app/(tabs)/homepage.tsx b/app/(tabs)/homepage.tsx
deleted file mode 100644
index 8201758..0000000
--- a/app/(tabs)/homepage.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import { View } from "react-native";
-
-interface HomePageProps {}
-
-const HomePage = ({}: HomePageProps) => {
- return ;
-};
-
-export default HomePage;
diff --git a/app/(tabs)/my/_layout.tsx b/app/(tabs)/my/_layout.tsx
new file mode 100644
index 0000000..66e8440
--- /dev/null
+++ b/app/(tabs)/my/_layout.tsx
@@ -0,0 +1,16 @@
+import { globalGray50 } from "@/shared/ui";
+import { Stack } from "expo-router";
+
+export default function MyLayout() {
+ return (
+
+
+
+ );
+}
diff --git a/app/(tabs)/my/index.tsx b/app/(tabs)/my/index.tsx
new file mode 100644
index 0000000..1c6cf08
--- /dev/null
+++ b/app/(tabs)/my/index.tsx
@@ -0,0 +1,15 @@
+import { StyleSheet, Text, View } from "react-native";
+
+interface MyScreenProps {}
+
+const MyScreen = ({}: MyScreenProps) => {
+ return (
+
+ MyScreen
+
+ );
+};
+
+const styles = StyleSheet.create({});
+
+export default MyScreen;
diff --git a/app/(tabs)/mypage.tsx b/app/(tabs)/mypage.tsx
deleted file mode 100644
index 00e4b0d..0000000
--- a/app/(tabs)/mypage.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import { View } from "react-native";
-
-interface MyPageProps {}
-
-const MyPage = ({}: MyPageProps) => {
- return ;
-};
-
-export default MyPage;
diff --git a/app/(tabs)/personal/_layout.tsx b/app/(tabs)/personal/_layout.tsx
new file mode 100644
index 0000000..d876693
--- /dev/null
+++ b/app/(tabs)/personal/_layout.tsx
@@ -0,0 +1,15 @@
+import { globalGray50 } from "@/shared/ui";
+import { Stack } from "expo-router";
+
+export default function PersonalLayout() {
+ return (
+
+
+
+ );
+}
diff --git a/app/(tabs)/personal/index.tsx b/app/(tabs)/personal/index.tsx
new file mode 100644
index 0000000..ca22075
--- /dev/null
+++ b/app/(tabs)/personal/index.tsx
@@ -0,0 +1,15 @@
+import { StyleSheet, Text, View } from "react-native";
+
+interface PersonalScreenProps {}
+
+const PersonalScreen = ({}: PersonalScreenProps) => {
+ return (
+
+ PersonalPage
+
+ );
+};
+
+const styles = StyleSheet.create({});
+
+export default PersonalScreen;
diff --git a/app/_layout.tsx b/app/_layout.tsx
index db2fa6b..6d9fcd7 100644
--- a/app/_layout.tsx
+++ b/app/_layout.tsx
@@ -1,5 +1,18 @@
-import { Tabs } from "expo-router";
+import { globalGray50 } from "@/shared/ui";
+import { Stack } from "expo-router";
+import { SafeAreaProvider } from "react-native-safe-area-context";
export default function RootLayout() {
- return ;
+ return (
+
+
+
+
+
+ );
}
diff --git a/app/index.tsx b/app/index.tsx
index 866b635..517880d 100644
--- a/app/index.tsx
+++ b/app/index.tsx
@@ -1,15 +1,6 @@
-import { Text, View } from "react-native";
+import { Redirect } from "expo-router";
export default function Index() {
- return (
-
- Edit app/index.tsx to edit this screen.
-
- );
+ // auth 구현 전, 개발 편의를 위해 초기 진입 시 홈으로 리다이렉트
+ return ;
}
diff --git a/app/sideModal 2.tsx b/app/sideModal 2.tsx
deleted file mode 100644
index 6e05ca3..0000000
--- a/app/sideModal 2.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import { View } from "react-native";
-
-interface SideModalProps {}
-
-const SideModal = ({}: SideModalProps) => {
- return ;
-};
-
-export default SideModal;
diff --git a/app/sideModal.tsx b/app/sideModal.tsx
deleted file mode 100644
index 6e05ca3..0000000
--- a/app/sideModal.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import { View } from "react-native";
-
-interface SideModalProps {}
-
-const SideModal = ({}: SideModalProps) => {
- return ;
-};
-
-export default SideModal;
diff --git a/assets/icons/main.tsx b/assets/icons/main.tsx
new file mode 100644
index 0000000..b3049c3
--- /dev/null
+++ b/assets/icons/main.tsx
@@ -0,0 +1,33 @@
+import { globalGray500 } from "@/shared/ui";
+import * as React from "react";
+import Svg, { Path, SvgProps } from "react-native-svg";
+
+interface MainIconProps extends SvgProps {
+ size?: number;
+ color?: string;
+}
+
+const MainIcon = ({
+ size = 24,
+ color = globalGray500,
+ ...props
+}: MainIconProps) => (
+
+);
+
+export default MainIcon;
diff --git a/assets/icons/mypage.tsx b/assets/icons/mypage.tsx
new file mode 100644
index 0000000..501c1c0
--- /dev/null
+++ b/assets/icons/mypage.tsx
@@ -0,0 +1,43 @@
+import { globalGray500 } from "@/shared/ui";
+import * as React from "react";
+import Svg, { Path, SvgProps } from "react-native-svg";
+
+interface MyPageIconProps extends SvgProps {
+ size?: number;
+ color?: string;
+}
+
+const MyPageIcon = ({
+ size = 24,
+ color = globalGray500,
+ ...props
+}: MyPageIconProps) => (
+
+);
+
+export default MyPageIcon;
diff --git a/assets/icons/personal.tsx b/assets/icons/personal.tsx
new file mode 100644
index 0000000..214bf23
--- /dev/null
+++ b/assets/icons/personal.tsx
@@ -0,0 +1,54 @@
+import { globalGray500 } from "@/shared/ui";
+import * as React from "react";
+import Svg, { Path, SvgProps } from "react-native-svg";
+
+interface PersonalIconProps extends SvgProps {
+ size?: number;
+ color?: string;
+}
+
+const PersonalIcon = ({
+ size = 24,
+ color = globalGray500,
+ ...props
+}: PersonalIconProps) => (
+
+);
+
+export default PersonalIcon;
diff --git a/shared/stories/atoms/Input.stories.tsx b/shared/stories/atoms/Input.stories.tsx
index 96e4e76..d6fc2e4 100644
--- a/shared/stories/atoms/Input.stories.tsx
+++ b/shared/stories/atoms/Input.stories.tsx
@@ -1,9 +1,18 @@
+import { globalGray50 } from "@/shared/ui";
import type { Meta, StoryObj } from "@storybook/react";
+import { View } from "react-native";
import Input from "../../ui/atoms/Input";
const meta: Meta = {
title: "atoms/Input",
component: Input,
+ decorators: [
+ (Story) => (
+
+
+
+ ),
+ ],
};
export default meta;
diff --git a/shared/stories/organisms/AlertModal.stories.tsx b/shared/stories/organisms/AlertModal.stories.tsx
index 9a44d81..9e8c358 100644
--- a/shared/stories/organisms/AlertModal.stories.tsx
+++ b/shared/stories/organisms/AlertModal.stories.tsx
@@ -1,4 +1,5 @@
import type { Meta, StoryObj } from "@storybook/react";
+import { useState } from "react";
import { View } from "react-native";
import { globalGray100 } from "../../ui/index";
import AlertModal from "../../ui/organisms/AlertModal";
@@ -26,62 +27,163 @@ type Story = StoryObj;
// 1. 버튼 하나
export const SingleButton: Story = {
- args: {
- title: "알림",
- content: "작업이 완료되었습니다.",
- confirmLabel: "확인",
- onConfirm: () => {
- console.log("확인 클릭");
- },
- },
+ render: () => (
+
+ 탈퇴할까요?
+ {
+ console.log("확인 클릭");
+ }}
+ />
+
+ ),
};
-// 2. 버튼 두 개
+// 2. 버튼 둘
export const TwoButtons: Story = {
- args: {
- title: "알림",
- content: "이 작업을 진행하시겠습니까?",
- cancelLabel: "취소",
- confirmLabel: "확인",
- onCancel: () => {
- console.log("취소 클릭");
- },
- onConfirm: () => {
- console.log("확인 클릭");
- },
- },
+ render: () => (
+
+ 탈퇴하기
+ {
+ console.log("취소 클릭");
+ }}
+ onConfirm={() => {
+ console.log("확인 클릭");
+ }}
+ />
+
+ ),
};
-// 3. 이미지 있음
-export const WithDefaultProfileImage: Story = {
- args: {
- title: "모달 타이틀",
- content: "모달 본문내용 모달 본문내용 모달 본문내용 모달 본문내용",
- confirmLabel: "맞아요",
- onConfirm: () => {
- console.log("확인 클릭");
- },
- },
- render: (args) => (
-
+// 3. 타이틀 + 설명 + 버튼 2개
+export const WithText: Story = {
+ render: () => (
+
+ 탈퇴하기
+ 계정을 삭제하시고 싶으신가요?
+ {
+ console.log("취소 클릭");
+ }}
+ onConfirm={() => {
+ console.log("확인 클릭");
+ }}
+ />
+
+ ),
+};
+
+// 4. 프로필 이미지 + 타이틀 + 설명 + 버튼 2개
+export const WithProfileImage: Story = {
+ render: () => (
+
+ 탈퇴하기
+ 계정을 삭제하시고 싶으신가요?
+ {
+ console.log("취소 클릭");
+ }}
+ onConfirm={() => {
+ console.log("확인 클릭");
+ }}
+ />
),
};
-// 4. 긴 텍스트
-export const LongContent: Story = {
- args: {
- title: "긴 제목이 들어가는 경우 테스트",
- content:
- "이것은 매우 긴 콘텐츠 텍스트입니다. 모달의 width가 화면 크기에 따라 조절되고, 콘텐츠는 자동으로 wrap되어야 합니다. 여러 줄에 걸쳐 표시되는 긴 텍스트를 테스트하기 위한 예시입니다.",
- cancelLabel: "취소",
- confirmLabel: "확인",
- onCancel: () => {
- console.log("취소 클릭");
- },
- onConfirm: () => {
- console.log("확인 클릭");
- },
+// 5. 타이틀 + 설명 + Input + 버튼 2개
+export const WithTextAndInput: Story = {
+ render: () => {
+ const [inputValue, setInputValue] = useState("");
+
+ return (
+
+ 탈퇴하기
+
+ 계정을 삭제하려면 탈퇴하기를 입력해주세요
+
+
+ {
+ console.log("취소 클릭");
+ setInputValue("");
+ }}
+ onConfirm={() => {
+ console.log("확인 클릭", inputValue);
+ setInputValue("");
+ }}
+ />
+
+ );
+ },
+};
+
+// 6. 타이틀 + Input만
+export const WithInputOnly: Story = {
+ render: () => {
+ const [inputValue, setInputValue] = useState("");
+
+ return (
+
+ 이름 변경
+
+ {
+ console.log("취소 클릭");
+ setInputValue("");
+ }}
+ onConfirm={() => {
+ console.log("저장 클릭", inputValue);
+ setInputValue("");
+ }}
+ />
+
+ );
},
};
+
+// 7. 계정 완전 삭제 확인 (실제 이미지 케이스)
+export const DeleteAccountConfirmation: Story = {
+ render: () => (
+
+ 탈퇴하기
+
+ 계정이 탈퇴되었습니다. {"\n"} 그동안 이용해주셔서 감사합니다.
+
+ {
+ console.log("확인 클릭");
+ }}
+ />
+
+ ),
+};
diff --git a/shared/ui/atoms/Input.tsx b/shared/ui/atoms/Input.tsx
index 495bb5a..e332dca 100644
--- a/shared/ui/atoms/Input.tsx
+++ b/shared/ui/atoms/Input.tsx
@@ -5,20 +5,43 @@ import {
TextInputProps,
View,
} from "react-native";
-import { globalGray200, globalGray600, globalRed50, globalRed600 } from "..";
+import {
+ globalGray0,
+ globalGray50,
+ globalGray600,
+ globalRed50,
+ globalRed600,
+} from "..";
+
+type InputVariant = "default" | "modal";
interface InputProps extends TextInputProps {
label?: string;
isError?: boolean;
+ variant?: InputVariant;
}
-const Input = ({ label, isError = false, ...props }: InputProps) => {
+const Input = ({
+ label,
+ isError = false,
+ variant = "default",
+ ...props
+}: InputProps) => {
+ const containerStyle =
+ variant === "modal" ? styles.containerModal : styles.containerDefault;
+
+ const textStyle =
+ variant === "modal" ? styles.inputModal : styles.inputDefault;
+
return (
- {label && {label}}
+ {label && variant === "default" && (
+ {label}
+ )}
{
>
@@ -36,14 +59,21 @@ const Input = ({ label, isError = false, ...props }: InputProps) => {
};
const styles = StyleSheet.create({
- container: {
+ containerBase: {
alignSelf: "stretch",
minHeight: 48,
borderRadius: 8,
justifyContent: "center",
- borderWidth: 1,
- borderColor: globalGray200,
paddingRight: 12,
+ borderWidth: 1,
+ },
+ containerDefault: {
+ backgroundColor: globalGray0,
+ borderColor: globalGray0,
+ },
+ containerModal: {
+ backgroundColor: globalGray50,
+ borderColor: globalGray50,
},
label: {
fontFamily: "Pretendard-Regular",
@@ -52,18 +82,20 @@ const styles = StyleSheet.create({
fontSize: 14,
marginBottom: 12,
},
- input: {
+ inputBase: {
fontFamily: "Pretendard-Regular",
fontWeight: "400",
fontSize: 14,
- flex: 1, // 컨테이너의 남은 가로 공간을 다 사용
+ flex: 1,
marginLeft: 12,
letterSpacing: 0,
paddingVertical: 0,
},
- placeholder: {
- color: globalGray600,
- fontWeight: "400",
+ inputDefault: {
+ lineHeight: 16, // body2
+ },
+ inputModal: {
+ lineHeight: 20, // body2wide
},
});
diff --git a/shared/ui/atoms/NemoText.tsx b/shared/ui/atoms/NemoText.tsx
index c04fe9d..4a62711 100644
--- a/shared/ui/atoms/NemoText.tsx
+++ b/shared/ui/atoms/NemoText.tsx
@@ -78,6 +78,27 @@ const style = StyleSheet.create({
lineHeight: 18,
letterSpacing: 0,
},
+ text_body2Tight: {
+ fontWeight: "400",
+ fontFamily: "Pretendard-Regular",
+ fontSize: 14,
+ lineHeight: 16,
+ letterSpacing: 0,
+ },
+ text_body2wide: {
+ fontWeight: "400",
+ fontFamily: "Pretendard-Regular",
+ fontSize: 14,
+ lineHeight: 20,
+ letterSpacing: 0,
+ },
+ text_caption: {
+ fontWeight: "600",
+ fontFamily: "Pretendard-Regular",
+ fontSize: 12,
+ lineHeight: 14,
+ letterSpacing: 0,
+ },
});
export default NemoText;
diff --git a/shared/ui/atoms/ProfileImage.tsx b/shared/ui/atoms/ProfileImage.tsx
index be52805..be0d0f6 100644
--- a/shared/ui/atoms/ProfileImage.tsx
+++ b/shared/ui/atoms/ProfileImage.tsx
@@ -1,4 +1,4 @@
-import { Image } from "react-native";
+import { Image, StyleSheet, View } from "react-native";
const defaultUserImage = require("../../../assets/icons/user.svg");
@@ -10,7 +10,17 @@ interface ProfileImageProps {
const ProfileImage = ({ uri, size }: ProfileImageProps) => {
const imageSource = uri ? { uri } : defaultUserImage;
- return ;
+ return (
+
+
+
+ );
};
+const styles = StyleSheet.create({
+ container: {
+ alignItems: "center",
+ },
+});
+
export default ProfileImage;
diff --git a/shared/ui/molecules/AlertModalAction.tsx b/shared/ui/molecules/AlertModalAction.tsx
new file mode 100644
index 0000000..6f9bacf
--- /dev/null
+++ b/shared/ui/molecules/AlertModalAction.tsx
@@ -0,0 +1,71 @@
+import { StyleSheet, View } from "react-native";
+import { globalSpacingXs } from "../index";
+import ModalButton from "./ModalButton";
+
+interface SingleButtonActionsProps {
+ type: "single";
+ confirmLabel: string;
+ onConfirm: () => void;
+}
+
+interface DoubleButtonActionsProps {
+ type: "double";
+ cancelLabel: string;
+ confirmLabel: string;
+ onCancel: () => void;
+ onConfirm: () => void;
+}
+
+type AlertModalActionsProps =
+ | SingleButtonActionsProps
+ | DoubleButtonActionsProps;
+
+/**
+ * 모달 액션 버튼들
+ */
+const AlertModalActions = (props: AlertModalActionsProps) => {
+ if (props.type === "single") {
+ return (
+
+
+
+
+
+ );
+ }
+
+ return (
+
+
+
+
+
+
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flexDirection: "row",
+ gap: globalSpacingXs,
+ },
+ buttonWrapper: {
+ flex: 1,
+ },
+});
+
+export default AlertModalActions;
diff --git a/shared/ui/molecules/AlertModalInput.tsx b/shared/ui/molecules/AlertModalInput.tsx
new file mode 100644
index 0000000..2a5bf5d
--- /dev/null
+++ b/shared/ui/molecules/AlertModalInput.tsx
@@ -0,0 +1,17 @@
+// AlertModalInput.tsx
+import { TextInputProps, View } from "react-native";
+import Input from "../atoms/Input";
+
+interface AlertModalInputProps extends TextInputProps {
+ isError?: boolean;
+}
+
+const AlertModalInput = ({ ...props }: AlertModalInputProps) => {
+ return (
+
+
+
+ );
+};
+
+export default AlertModalInput;
diff --git a/shared/ui/molecules/AlertModalText.tsx b/shared/ui/molecules/AlertModalText.tsx
new file mode 100644
index 0000000..132b6bd
--- /dev/null
+++ b/shared/ui/molecules/AlertModalText.tsx
@@ -0,0 +1,32 @@
+import { StyleSheet, View } from "react-native";
+import NemoText from "../atoms/NemoText";
+import { globalGray700 } from "../index";
+
+interface AlertModalTextProps {
+ children: React.ReactNode;
+}
+
+/**
+ * 모달 설명 텍스트
+ */
+const AlertModalText = ({ children }: AlertModalTextProps) => {
+ return (
+
+
+ {children}
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ alignItems: "center",
+ },
+ text: {
+ color: globalGray700,
+ textAlign: "center",
+ },
+});
+
+export default AlertModalText;
diff --git a/shared/ui/molecules/AlertModalTitle.tsx b/shared/ui/molecules/AlertModalTitle.tsx
new file mode 100644
index 0000000..f5cfb7b
--- /dev/null
+++ b/shared/ui/molecules/AlertModalTitle.tsx
@@ -0,0 +1,25 @@
+import { StyleSheet, View } from "react-native";
+import NemoText from "../atoms/NemoText";
+
+interface AlertModalTitleProps {
+ children: string;
+}
+
+/**
+ * 모달 타이틀
+ */
+const AlertModalTitle = ({ children }: AlertModalTitleProps) => {
+ return (
+
+ {children}
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ alignItems: "center",
+ },
+});
+
+export default AlertModalTitle;
diff --git a/shared/ui/organisms/AlertModal.tsx b/shared/ui/organisms/AlertModal.tsx
index 4dc4a44..867fae3 100644
--- a/shared/ui/organisms/AlertModal.tsx
+++ b/shared/ui/organisms/AlertModal.tsx
@@ -1,121 +1,96 @@
import { StyleSheet, View } from "react-native";
-import NemoText from "../atoms/NemoText";
+import { globalGray0, globalSpacingLg, globalSpacingSm } from "../index";
+
import ProfileImage from "../atoms/ProfileImage";
-import {
- globalGray0,
- globalGray700,
- globalSpacingLg,
- globalSpacingSm,
- globalSpacingXs,
-} from "../index";
-import ModalButton from "../molecules/ModalButton";
+import AlertModalActions from "../molecules/AlertModalAction";
+import AlertModalInput from "../molecules/AlertModalInput";
+import AlertModalText from "../molecules/AlertModalText";
+import AlertModalTitle from "../molecules/AlertModalTitle";
interface AlertModalProps {
- children?: React.ReactNode;
- title: string;
- content?: string;
- cancelLabel?: string;
- confirmLabel: string;
- onCancel?: () => void;
- onConfirm: () => void;
+ children: React.ReactNode;
}
/**
- * AlertModal 컴포넌트
+ * AlertModal - Compound Component Pattern
+ *
+ * 각 하위 컴포넌트를 조합하여 다양한 형태의 모달 구성 가능
*
* @example
- * // 버튼 하나만
- * {}}
- * />
+ * // 기본 확인 모달
+ *
+ * 알림
+ * 작업이 완료되었습니다.
+ * {}}
+ * />
+ *
*
* @example
- * // 버튼 두 개
- * {}}
- * onConfirm={() => {}}
- * />
+ * // 이미지 + 타이틀 + 설명
+ *
+ *
+ * 사용자 정보
+ * 정보를 수정하시겠습니까?
+ * {}}
+ * onConfirm={() => {}}
+ * />
+ *
*
* @example
- * // 프로필 이미지 포함 (기본 이미지)
- * {}}
- * >
- *
+ * // 타이틀 + 설명 + Input
+ *
+ * 탈퇴하기
+ *
+ * 계정을 삭제하려면 탈퇴하기를 입력해주세요
+ *
+ *
+ * {}}
+ * onConfirm={() => {}}
+ * />
*
*
* @example
- * // 프로필 이미지 포함 (커스텀 이미지)
- * {}}
- * onConfirm={() => {}}
- * >
- *
+ * // 타이틀 + Input만
+ *
+ * 이름 변경
+ *
+ * {}}
+ * onConfirm={() => {}}
+ * />
*
*/
-
-const AlertModal = ({
- title,
- content,
- cancelLabel,
- confirmLabel,
- onCancel,
- onConfirm,
- children,
-}: AlertModalProps) => {
- return (
-
- {children && {children}}
-
-
- {title}
-
-
- {content && (
-
-
- {content}
-
-
- )}
-
-
- {cancelLabel && onCancel && (
-
-
-
- )}
-
-
-
-
-
- );
+const AlertModal = ({ children }: AlertModalProps) => {
+ return {children};
};
-// Composition을 위해 ProfileImage를 붙임
+// Compound Components
+AlertModal.Title = AlertModalTitle;
+AlertModal.Text = AlertModalText;
+AlertModal.Input = AlertModalInput;
+AlertModal.Actions = AlertModalActions;
AlertModal.ProfileImage = ProfileImage;
const styles = StyleSheet.create({
@@ -128,22 +103,6 @@ const styles = StyleSheet.create({
padding: globalSpacingLg,
alignSelf: "center",
},
- image: {
- alignItems: "center",
- },
- title: {
- alignItems: "center",
- },
- content: {
- alignItems: "center",
- },
- footer: {
- flexDirection: "row",
- gap: globalSpacingXs,
- },
- buttonWrapper: {
- flex: 1,
- },
});
export default AlertModal;