diff --git a/apps/web/app/page.tsx b/apps/web/app/page.tsx
index d272393e..d616b7de 100644
--- a/apps/web/app/page.tsx
+++ b/apps/web/app/page.tsx
@@ -1,5 +1,11 @@
"use client";
-import { Headers, Text } from "@tripie/design-system";
+import {
+ Drawer,
+ Headers,
+ MyButton,
+ Text,
+ useDrawer,
+} from "@tripie/design-system";
import Container from "@tripie/design-system/components/container/_container";
import UnstyledLink from "@tripie/design-system/components/typography/link/_link";
import Paragraph from "@tripie/design-system/components/typography/paragraph/_paragraph";
@@ -8,8 +14,9 @@ import ThemeButton from "../components/ThemeButton";
export default function Home() {
const text =
"Lorem, ipsum dolor sit amet consectetur adipisicing elit. Omnis\npariatur, ab voluptates saepe eum at excepturi, eaque accusamus labore\ntemporibus ex nostrum in hic iure porro quod doloribus deleniti! Qui.\ntemporibus ex nostrum in hic iure porro quod doloribus deleniti!";
+ const { isOpen, toggle, close, open } = useDrawer();
return (
-
+ <>
@@ -33,6 +40,11 @@ export default function Home() {
떡볶이
-
+
+ show contents
+ :)
+
+ 토글
+ >
);
}
diff --git a/packages/design-system/src/components/container/_container.module.scss b/packages/design-system/src/components/container/_container.module.scss
index a918396e..e9aacd22 100644
--- a/packages/design-system/src/components/container/_container.module.scss
+++ b/packages/design-system/src/components/container/_container.module.scss
@@ -25,6 +25,7 @@ $space-map: (
m: space(1rem),
sm: space(0.6rem),
xsm: space(0.2rem),
+ none: space(0),
);
@mixin margins($direction, $size) {
diff --git a/packages/design-system/src/components/container/_container.tsx b/packages/design-system/src/components/container/_container.tsx
index 43214abb..3c5c5f97 100644
--- a/packages/design-system/src/components/container/_container.tsx
+++ b/packages/design-system/src/components/container/_container.tsx
@@ -3,7 +3,7 @@ import { ReactNode } from "react";
import Style from "./_container.module.scss";
export type ContainerProps = {
- margin?: "xl" | "l" | "m" | "sm" | "xsm";
+ margin?: "xl" | "l" | "m" | "sm" | "xsm" | "none";
align?: "left" | "center" | "right";
children?: ReactNode;
applyMargin?:
@@ -38,7 +38,8 @@ const Container = ({
)}
{...props}
>
-
{children}
+ {children}
+ {/* {children}
*/}
);
};
diff --git a/packages/design-system/src/components/drawer/_drawer.module.scss b/packages/design-system/src/components/drawer/_drawer.module.scss
new file mode 100644
index 00000000..ed31a99e
--- /dev/null
+++ b/packages/design-system/src/components/drawer/_drawer.module.scss
@@ -0,0 +1,32 @@
+@use "../../functions/" as *;
+@use "../../mixins/" as *;
+@use "sass:map";
+
+.drawer-menu {
+ position: fixed;
+ z-index: z-index("modal");
+ width: min(100%, 32rem);
+ height: 100vh;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
+ background-color: color(default, 50);
+ display: grid;
+}
+
+.drawer-menu.is-closed {
+ transform: translateX(-100%);
+}
+
+.is-open {
+ top: 0;
+ left: 0;
+ position: fixed;
+ background-color: color(default, 800);
+ width: 100vw;
+ height: 100vh;
+ z-index: z-index("overlay");
+ bottom: 0;
+ opacity: 0.85;
+}
diff --git a/packages/design-system/src/components/drawer/_drawer.stories.tsx b/packages/design-system/src/components/drawer/_drawer.stories.tsx
new file mode 100644
index 00000000..089f4e8d
--- /dev/null
+++ b/packages/design-system/src/components/drawer/_drawer.stories.tsx
@@ -0,0 +1,55 @@
+import type { Meta, StoryObj } from "@storybook/react";
+import { useEffect } from "react";
+import { useAppTheme } from "../../hooks";
+import Drawer from "./_drawer";
+
+const meta: Meta = {
+ title: "tripie-ui/Drawer",
+ component: Drawer,
+ tags: ["autodocs"],
+ decorators: [
+ (story, context) => {
+ const { mode, setMode } = useAppTheme();
+ const selectedTheme = context.globals.theme || mode;
+
+ useEffect(() => {
+ setMode(selectedTheme);
+ }, [selectedTheme]);
+
+ return (
+
+ {story()}
+
+ );
+ },
+ ],
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {
+ name: "Default",
+ args: {
+ children: "default Drawer",
+ },
+};
+
+export const NoOverLayDrawer: Story = {
+ name: "No OverLay",
+ args: {
+ children: "Drawer No OverLay",
+ overlay: false,
+ },
+};
+
+export const NoCloseButtonDrawer: Story = {
+ name: "No Close Button",
+ args: {
+ children: "Drawer No Close Button",
+ withCloseButton: false,
+ },
+};
diff --git a/packages/design-system/src/components/drawer/_drawer.tsx b/packages/design-system/src/components/drawer/_drawer.tsx
new file mode 100644
index 00000000..5a1d9408
--- /dev/null
+++ b/packages/design-system/src/components/drawer/_drawer.tsx
@@ -0,0 +1,49 @@
+import classNames from "classnames/bind";
+import { ReactNode } from "react";
+import { useDrawerOutput } from "../../hooks";
+import Container from "../container";
+import MyButton from "../myButton";
+import Style from "./_drawer.module.scss";
+
+export type DrawerProps = {
+ children?: ReactNode;
+ overlay?: boolean;
+
+ withCloseButton?: boolean;
+} & Omit, "children"> &
+ Partial;
+
+const style = classNames.bind(Style);
+
+const Drawer = ({
+ children,
+ overlay = true,
+ withCloseButton = true,
+ isOpen,
+
+ close,
+}: DrawerProps) => {
+ return (
+ <>
+ {overlay ? (
+
+ ) : null}
+
+
+
+
+ {withCloseButton && close != null ? (
+
+ close()}>Close
+ {/* !! 아이콘으로 변경하기 */}
+
+ ) : null}
+ {children}
+
+
+
+ >
+ );
+};
+
+export default Drawer;
diff --git a/packages/design-system/src/components/drawer/index.ts b/packages/design-system/src/components/drawer/index.ts
new file mode 100644
index 00000000..4ba13829
--- /dev/null
+++ b/packages/design-system/src/components/drawer/index.ts
@@ -0,0 +1,2 @@
+export * from "./_drawer";
+export { default } from "./_drawer";
diff --git a/packages/design-system/src/components/index.ts b/packages/design-system/src/components/index.ts
index de23480a..a07d89ff 100644
--- a/packages/design-system/src/components/index.ts
+++ b/packages/design-system/src/components/index.ts
@@ -1,4 +1,5 @@
export { default as Body } from "./body";
+export { default as Drawer } from "./drawer";
export { default as MyButton } from "./myButton";
export { default as Headers } from "./typography";
export { default as Text } from "./typography/text";
diff --git a/packages/design-system/src/hooks/index.ts b/packages/design-system/src/hooks/index.ts
index 50644dca..c687959e 100644
--- a/packages/design-system/src/hooks/index.ts
+++ b/packages/design-system/src/hooks/index.ts
@@ -1 +1,2 @@
export * from "./useAppTheme";
+export * from "./useDrawer";
diff --git a/packages/design-system/src/hooks/useDrawer.ts b/packages/design-system/src/hooks/useDrawer.ts
new file mode 100644
index 00000000..84f42c5e
--- /dev/null
+++ b/packages/design-system/src/hooks/useDrawer.ts
@@ -0,0 +1,28 @@
+import { useState } from "react";
+
+const DRAWER_MODE = {
+ OPEN: true,
+ CLOSE: false,
+} as const;
+
+type DrawerMode = (typeof DRAWER_MODE)[keyof typeof DRAWER_MODE];
+
+export type useDrawerOutput = {
+ isOpen: DrawerMode;
+ toggle: () => void;
+ close: () => void;
+ open: () => void;
+};
+
+export const useDrawer = (): useDrawerOutput => {
+ const [isOpen, setIsOpen] = useState(DRAWER_MODE.CLOSE);
+
+ return {
+ isOpen,
+ toggle: () => {
+ setIsOpen((previous) => !previous);
+ },
+ open: () => setIsOpen(DRAWER_MODE.OPEN),
+ close: () => setIsOpen(DRAWER_MODE.CLOSE),
+ };
+};