Skip to content

Commit

Permalink
Merge pull request #153 from prgrms-web-devcourse-final-project/feature/
Browse files Browse the repository at this point in the history
#72

feat: MenuBottomSheet 컴포넌트 개발
  • Loading branch information
JW-Ahn0 authored Nov 29, 2024
2 parents e54b8c3 + 9f42319 commit 1513b14
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 9 deletions.
7 changes: 1 addition & 6 deletions src/components/molecules/KebabMenu/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import { TextButton } from "components/atoms";
import { KebabMenuWrapper } from "./styled";
import type { IMenu } from "types";

export interface IMenu {
/** 메뉴 이름 */
content: string;
/** 메뉴 아이템 클릭시 일어나는 이벤트 */
onClick: () => void;
}
interface IKebabMenuProps {
/** 케밥 메뉴 리스트 */
menus: IMenu[];
Expand Down
3 changes: 2 additions & 1 deletion src/components/molecules/KebabMenu/stories.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Meta, StoryObj } from "@storybook/react";
import { IMenu, KebabMenu } from ".";
import type { IMenu } from "types";
import { KebabMenu } from ".";

const meta: Meta<typeof KebabMenu> = {
title: "Molecules/KebabMenu",
Expand Down
31 changes: 31 additions & 0 deletions src/components/organisms/MenuBottomSheet/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { ComponentProps } from "react";
import { TextButton } from "components/atoms";
import { ModalBottomSheet } from "components/molecules";
import type { IMenu } from "types";
import { MenuBottomSheetWrapper } from "./styled";

interface IMenuBottomSheetProps
extends ComponentProps<typeof ModalBottomSheet> {
/** 메뉴 목록 */
menus: IMenu[];
}

export const MenuBottomSheet = ({
open,
onClose,
menus,
}: IMenuBottomSheetProps) => {
return (
<MenuBottomSheetWrapper open={open} onClose={onClose}>
{menus.map(({ content, onClick }, idx) => (
<TextButton
key={`bottom_menu_${idx}`}
text={content}
onClick={onClick}
backgroundColor="transparent"
size="l"
/>
))}
</MenuBottomSheetWrapper>
);
};
41 changes: 41 additions & 0 deletions src/components/organisms/MenuBottomSheet/stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { useState } from "react";
import type { Meta, StoryObj } from "@storybook/react";
import { MenuBottomSheet } from ".";

const meta: Meta<typeof MenuBottomSheet> = {
title: "Organisms/MenuBottomSheet",
component: MenuBottomSheet,
tags: ["autodocs"],
decorators: (story) => <div style={{ height: "300px" }}>{story()}</div>,
render: (args) => {
const Component = () => {
const [open, setOpen] = useState(args.open);
return (
<>
<button onClick={() => setOpen(true)}>Open</button>
<MenuBottomSheet
open={open}
onClose={() => setOpen(false)}
menus={args.menus}
/>
</>
);
};
return <Component />;
},
};

type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
open: true,
menus: [
{ content: "조기 종료", onClick: () => console.log("조기 종료") },
{ content: "게시글 수정", onClick: () => console.log("게시글 수정") },
{ content: "삭제", onClick: () => console.log("삭제") },
],
},
};

export default meta;
28 changes: 28 additions & 0 deletions src/components/organisms/MenuBottomSheet/styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { ComponentProps } from "react";
import styled, { type StyledComponent } from "@emotion/styled";
import { ModalBottomSheet } from "components/molecules";
import { TextButtonWrapper } from "components/atoms/Button/TextButton/styled";

export const MenuBottomSheetWrapper: StyledComponent<
ComponentProps<typeof ModalBottomSheet>
> = styled(ModalBottomSheet)`
display: flex;
flex-direction: column;
gap: 0.25rem;
padding: 0.125rem 0 0;
overflow: hidden;
${TextButtonWrapper} {
position: relative;
&:hover {
background-color: #f9f9f9;
}
&:not(:last-child)::after {
content: "";
display: block;
position: absolute;
bottom: -0.125rem;
width: 100%;
border-bottom: 1px solid #d9d9d9;
}
}
`;
4 changes: 2 additions & 2 deletions src/hooks/useKebabMenuManager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { IMenu } from "components/molecules/KebabMenu";
import { useCallback } from "react";
import type { IMenu } from "types";

export const useKebabMenuManager = () => {
const onReply = useCallback(() => {
Expand Down Expand Up @@ -41,7 +41,7 @@ export const useKebabMenuManager = () => {
return [];
}
},
[onBlock, onDelete, onEdit, onReply, onRepot]
[onBlock, onDelete, onEdit, onReply, onRepot],
);

return { getMenus };
Expand Down
1 change: 1 addition & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from "./navMenu";
export * from "./notification";
export * from "./user";
export * from "./chat";
export * from "./menu";
6 changes: 6 additions & 0 deletions src/types/menu.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface IMenu {
/** 메뉴 이름 */
content: string;
/** 메뉴 아이템 클릭시 일어나는 이벤트 */
onClick: () => void;
}

0 comments on commit 1513b14

Please sign in to comment.