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

[Feat/#60] 게시물 삭제 모달 구현 #64

Merged
merged 9 commits into from
Jan 16, 2025
19 changes: 15 additions & 4 deletions src/common/component/BottomSheet/BottomSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ interface BottomSheetPropTypes {
}

//화면 전체를 차지하는 바텀시트 틀 (children 필요)
const BottomSheet = ({ isOpen, children, handleOpen }: BottomSheetPropTypes) => {
const BottomSheet = ({
isOpen,
children,
handleOpen,
}: BottomSheetPropTypes) => {
if (!isOpen) return;

const handleClose = () => {
Expand All @@ -20,12 +24,19 @@ const BottomSheet = ({ isOpen, children, handleOpen }: BottomSheetPropTypes) =>
};

return (
<div className={styles.overlay} onClick={handleClose} onKeyDown={handleClose}>
<div
className={styles.overlay}
onClick={handleClose}
onKeyDown={handleClose}
>
<div className={styles.bottomSheet} onClick={handleBottomSheetClick}>
<div className={styles.bottomTabBar}>
<div className={styles.bar} onClick={handleClose} onKeyDown={handleClose} />
<div
className={styles.bar}
onClick={handleClose}
onKeyDown={handleClose}
/>
</div>

{children}
</div>
</div>
Expand Down
2 changes: 2 additions & 0 deletions src/page/community/[postId]/Post.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { style } from "@vanilla-extract/css";
import { color } from "@style/styles.css.ts";
27 changes: 26 additions & 1 deletion src/page/community/[postId]/Post.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
import MoreModal from "@shared/component/MoreModal/MoreModal.tsx";
import useMoreModal from "@shared/hook/useMoreModal";

const PostDetail = () => {
return <div>Postid</div>;
const { isOpen, openModal, closeModal, toggleModal } = useMoreModal();

const handleDelete = () => {
alert("삭제되었습니다!");
toggleModal();
};

return (
<div>
<MoreModal
isOpen={isOpen}
onToggleModal={toggleModal}
onDelete={handleDelete}
/>
<MoreModal
isOpen={isOpen}
onToggleModal={toggleModal}
onDelete={handleDelete}
iconSize="20"
onEdit={() => alert("수정하기")}
/>
</div>
);
};

export default PostDetail;
140 changes: 140 additions & 0 deletions src/shared/component/MoreModal/MoreModal.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import { style } from "@vanilla-extract/css";
import { recipe, RecipeVariants } from "@vanilla-extract/recipes";
import { button } from "@common/component/Button/styles.css.ts";
import { color, font } from "@style/styles.css.ts";

export const container = recipe({
base: {
margin: "20rem",
Copy link
Collaborator

Choose a reason for hiding this comment

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

p4) 혹시 이 마진은 왜 존재하는건가요? 20rem 이면 꽤 큰 거 같은데,
MoreModal 을 사용하려면 항상 상,하,좌,우 모달 주변에 마진이 필요했던 이유가 있나요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

마진은 없는 게 맞습니다.
테스트 하려다 모달이 안 보여서 움직여둔 겁니다!
삭제 후 푸시 했습니다

position: "relative",
width: "2.4rem",
},
variants: {
iconSize: {
"24": {
width: "2.4rem",
height: "2.4rem",
},
"20": {
width: "2.0rem",
height: "2.0rem",
},
},
Copy link
Collaborator

Choose a reason for hiding this comment

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

p2) 이렇게 하면 iconSize가 2가지의 경우로밖에 분리가 안되고, 매번 다른 사이즈의 아이콘이 필요하다면
그때마다 스타일링 variant를 작성해주어야한다는 불편함이 있어요.

export const iconSizeVar = createVar();

export const container = style({
  margin: "20rem",
  position: "relative",
  width: iconSizeVar, // 동적 크기 설정
  height: iconSizeVar, // 동적 크기 설정
});

이런 형식으로 만들어두고, 실제로 사용할 떄는

 <div
      className={styles.container}
      style={{
        [styles.iconSizeVar]: `${size}rem`, // CSS 변수에 동적 값 설정
      }}
    >
      Icon
    </div>

과 같은 방식으로 개선해보는건 어떨까요?

Copy link
Collaborator Author

@minjeoong minjeoong Jan 16, 2025

Choose a reason for hiding this comment

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

피드백 감사합니다!
해당 방법은 다양한 사이즈가 사용 될 때 유용한 것 같아요!

해당 아이콘은 두가지 사이즈(20,24) 만 쓰이고 있기도 하고,
20을 받으면 2 로 변환하는 것
24를 받으면 2.4 로 변환하는 것

해당 두가지 이슈가 있어서
props로 2 or 2.4를 받는 게 맞을까 생각해봤을 때,, 불편할 것 같다는 생각이 들었어요.

또한 해당 코드 기반으로 방금 변경 사항 적용을 해보았는데, CSS 변수(createVar)와 React 스타일 속성 사용의 혼용으로 스타일이 안 먹는 것 같습니다...

어떻게 하면 좋을지 얘기해보면 좋을 것 같아요

Copy link
Collaborator

Choose a reason for hiding this comment

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

assginInLineVars 함수를 사용해서 할당을 해야해요!
구두로 설명드리겠습니다 ~

},
});

export const moreIcon = recipe({
base: {
width: "2.4rem",
height: "2.4rem",
},
variants: {
iconSize: {
"24": {
width: "2.4rem",
height: "2.4rem",
},
"20": {
width: "2.0rem",
height: "2.0rem",
},
},
Copy link
Collaborator

Choose a reason for hiding this comment

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

p2) 이것도! 위에서 언급했으니 자세한 설명은 생략할게요~

},
});

export type MoreIconProps = RecipeVariants<typeof moreIcon>;

export const moreModal = recipe({
base: {
position: "absolute",
top: "calc(100% + 0.8rem)",
left: "-16rem",
display: "flex",
flexDirection: "column",
borderRadius: "1.2rem",
backgroundColor: "white",
boxShadow: "0px 2px 10px 0px rgba(0, 0, 0, 0.15)",
width: "18.4rem",
zIndex: 10,
},
variants: {
onEdit: {
true: {
// 수정하기가 있을 때
height: "11.2rem",
},
false: {
// 수정하기가 없을 때
height: "5.6rem",
},
},
},
defaultVariants: {
onEdit: false, // 기본값
},
});

// export const moreModalItem = style([
// font.body01,
// {
// background: "none",
// border: "none",
// borderRadius: "1.2rem",
// textAlign: "left",
// width: "100%",
// padding: "1.8rem 3.2rem",
// color: color.red.warning_red200,
// ":hover": {
// borderRadius: "unset",
// backgroundColor: color.gray.gray300,
// },
// ":active": {
// backgroundColor: color.gray.gray300,
// },
// },
// ]);

export const moreModalItem = recipe({
base: [
font.body01,
{
background: "none",
border: "none",
textAlign: "left",
width: "100%",
padding: "1.8rem 3.2rem",
color: color.red.warning_red200,
":hover": {
backgroundColor: color.gray.gray300,
},
":active": {
backgroundColor: color.gray.gray300,
},
},
],
variants: {
position: {
first: {
// 수정하기가 들어간 경우의 삭제하기 border
borderRadius: "1.2rem 1.2rem 0 0",
},
last: {
// 수정하기가 들어간 경우의 수정하기 border
borderRadius: "0 0 1.2rem 1.2rem",
},
default: {
// 수정하기가 없는 경우의 border
borderRadius: "1.2rem",
},
},
},
defaultVariants: {
position: "default",
},
});

export const moreModalDivider = style({
height: "1px",
backgroundColor: color.gray.gray300,
margin: "0",
});
60 changes: 60 additions & 0 deletions src/shared/component/MoreModal/MoreModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React from "react";
import { IcEllipses } from "@asset/svg";
import {
container,
moreIcon,
MoreIconProps,
moreModal,
moreModalDivider,
moreModalItem,
} from "@shared/component/MoreModal/MoreModal.css.ts";

interface MoreModalParams {
isOpen: boolean;
onToggleModal: () => void;
onDelete: () => void;
onEdit?: () => void; // 선택적 수정하기 동작
}

type MoreModalProps = MoreModalParams & MoreIconProps;

const MoreModal = ({
isOpen,
onToggleModal,
onDelete,
iconSize,
onEdit,
}: MoreModalProps) => {
return (
<div className={container({ iconSize })}>
<IcEllipses className={moreIcon({ iconSize })} onClick={onToggleModal} />
{isOpen && (
<div className={moreModal({ onEdit: !!onEdit })}>
<button
className={moreModalItem({
position: !!onEdit ? "first" : "default",
})}
onClick={onDelete}
>
삭제하기
</button>
{onEdit && (
<>
<div className={moreModalDivider} />
<button
className={moreModalItem({
position: !!onEdit ? "last" : "default",
})}
onClick={onEdit}
>
수정하기
</button>
</>
)}
</div>
)}
</div>
);
};

export default MoreModal;
Empty file removed src/shared/constant/.gitkeep
Empty file.
Empty file removed src/shared/hook/.gitkeep
Empty file.
13 changes: 13 additions & 0 deletions src/shared/hook/useMoreModal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { useState } from "react";

const useMoreModal = () => {
const [isOpen, setIsOpen] = useState(false);

const openModal = () => setIsOpen(true);
const closeModal = () => setIsOpen(false);
const toggleModal = () => setIsOpen((prev) => !prev);

return { isOpen, openModal, closeModal, toggleModal };
};

export default useMoreModal;
Loading