From 1b110a414eb25387665f8207bec23a2fe9666897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=96=91=ED=98=9C=EC=A7=84?= Date: Thu, 4 Apr 2024 10:18:39 +0900 Subject: [PATCH 01/19] feat: add Dialog component --- .../src/components/Dialog/Dialog.styled.ts | 141 ++++++++++++++++++ .../src/components/Dialog/Dialog.tsx | 129 ++++++++++++++++ .../Dialog/components/DialogAction.tsx | 36 +++++ .../Dialog/components/DialogContent.tsx | 28 ++++ .../Dialog/components/DialogTitle.tsx | 67 +++++++++ .../src/components/Dialog/index.ts | 4 + .../src/components/Dialog/useDialog.ts | 10 ++ 7 files changed, 415 insertions(+) create mode 100644 packages/design-system/src/components/Dialog/Dialog.styled.ts create mode 100644 packages/design-system/src/components/Dialog/Dialog.tsx create mode 100644 packages/design-system/src/components/Dialog/components/DialogAction.tsx create mode 100644 packages/design-system/src/components/Dialog/components/DialogContent.tsx create mode 100644 packages/design-system/src/components/Dialog/components/DialogTitle.tsx create mode 100644 packages/design-system/src/components/Dialog/index.ts create mode 100644 packages/design-system/src/components/Dialog/useDialog.ts diff --git a/packages/design-system/src/components/Dialog/Dialog.styled.ts b/packages/design-system/src/components/Dialog/Dialog.styled.ts new file mode 100644 index 00000000..5dc4ac11 --- /dev/null +++ b/packages/design-system/src/components/Dialog/Dialog.styled.ts @@ -0,0 +1,141 @@ +import { styled } from "@mui/material/styles"; + +import type { DialogPropsBase } from "./Dialog"; +import type { CSSObject } from "@mui/material/styles"; + +export interface DialogElementStyle { + [key: string]: CSSObject; +} + +export type DialogStyle = Pick; + +const DIALOG_WRAPPER_STYLE: DialogElementStyle = { + small: { + width: "320px", + maxWidth: "320px", + }, + medium: { + width: "500px", + maxWidth: "840px", + }, + modal: { + position: "relative", + boxShadow: + "0px 12px 24px 8px rgba(0, 0, 0, 0.12), 0px 12px 44px 3px rgba(0, 0, 0, 0.18)", + }, + nonModal: { + position: "fixed", + top: "30px", + right: "30px", + boxShadow: + "0px 12px 24px 8px rgba(0, 0, 0, 0.36), 0px 12px 44px 3px rgba(0, 0, 0, 0.48)", + }, +}; + +const DIALOG_TITLE_STYLE: DialogElementStyle = { + small: { + height: "52px", + maxHeight: "100%", + padding: "20px 20px 8px 20px", + }, + medium: { + height: "64px", + maxHeight: "100%", + padding: "30px 32px 6px 32px", + }, +}; + +const DIALOG_CONTENT_STYLE: DialogElementStyle = { + small: { + paddingInline: "20px calc(20px - 10px)", + paddingBottom: "28px", + }, + smallAction: { + paddingInline: "20px calc(20px - 10px)", + paddingBottom: "8px", + }, + medium: { + paddingInline: "32px calc(32px - 14px)", + paddingBottom: "32px", + }, + mediumAction: { + paddingInline: "32px calc(32px - 14px)", + paddingBottom: "16px", + }, +}; + +const DIALOG_ACTION_STYLE: DialogElementStyle = { + small: { + height: "64px", + padding: "8px 20px 20px 20px", + }, + medium: { + height: "84px", + padding: "16px 32px 32px 32px", + }, +}; + +export const StyledBackdrop = styled("div")({ + position: "fixed", + top: 0, + left: 0, + width: "100%", + height: "100%", + backgroundColor: "rgba(17, 17, 19, 0.7)", + zIndex: 1000, + display: "grid", + placeItems: "center", +}); + +export const StyledDialog = styled("div")( + ({ theme, isSmall, modalType }) => ({ + zIndex: 1001, + maxHeight: "80vh", + display: "flex", + flexDirection: "column", + boxSizing: "border-box", + borderRadius: "10px", + backgroundColor: theme.palette.common.white, + color: theme.palette.text.primary, + + ...DIALOG_WRAPPER_STYLE[isSmall ? "small" : "medium"], + ...DIALOG_WRAPPER_STYLE[modalType ? "modal" : "nonModal"], + + "& #dialog-title": { + ...DIALOG_TITLE_STYLE[isSmall ? "small" : "medium"], + }, + + "& #dialog-content": { + ...DIALOG_CONTENT_STYLE[ + isSmall && modalType !== "passive" + ? "smallAction" + : isSmall + ? "small" + : !isSmall && modalType !== "passive" + ? "mediumAction" + : "medium" + ], + + scrollbarGutter: "stable", + "::-webkit-scrollbar": { + width: isSmall ? "10px" : "14px", + }, + "::webkit-scrollbar-track": { + background: "transparent", + }, + "::-webkit-scrollbar-thumb": { + backgroundClip: "padding-box", + border: `2px solid transparent`, + /** + * Figma's border-radius is 6px, but actual border radius is 10px since padding 2px is added. + */ + borderRadius: "10px", + backgroundColor: theme.palette.lunit_token.component.scrollbars_bg, + }, + }, + + "& #dialog-action": { + ...DIALOG_ACTION_STYLE[isSmall ? "small" : "medium"], + }, + }) +); diff --git a/packages/design-system/src/components/Dialog/Dialog.tsx b/packages/design-system/src/components/Dialog/Dialog.tsx new file mode 100644 index 00000000..d3e626b9 --- /dev/null +++ b/packages/design-system/src/components/Dialog/Dialog.tsx @@ -0,0 +1,129 @@ +import React, { useEffect } from "react"; +import { createPortal } from "react-dom"; + +import { DialogAction } from "./components/DialogAction"; +import { StyledBackdrop, StyledDialog } from "./Dialog.styled"; + +import type { SxProps } from "@mui/material/styles"; + +export interface DialogPropsBase { + isOpen: boolean; + isSmall?: boolean; + modalType?: "passive" | "action"; + onClose(): void; + children: React.ReactNode; + sx?: SxProps; + style?: React.CSSProperties; + className?: string; +} + +export interface PassiveModalProps extends DialogPropsBase { + modalType: "passive"; + actions?: undefined; +} + +export interface ActionModalProps extends DialogPropsBase { + modalType: "action"; + actions: React.ReactNode; + enableBackdropClose?: boolean; +} + +export type ModalProps = PassiveModalProps | ActionModalProps; + +export interface NonModalProps extends DialogPropsBase { + modalType?: undefined; + actions: React.ReactNode; +} + +export type DialogProps = ModalProps | NonModalProps; + +function Dialog(props: DialogProps) { + const { isOpen, modalType, onClose } = props; + + const nonModal = !modalType; + const isActionModal = modalType === "action"; + const isPassiveModal = modalType === "passive"; + + function handleBackdropClose(e: React.MouseEvent) { + if (e.target !== e.currentTarget) return; + const enableBackdropClose = + isPassiveModal || (isActionModal && props.enableBackdropClose); + + if (!enableBackdropClose) return; + onClose(); + } + + useEffect(() => { + function handleEscClose(event: KeyboardEvent) { + if (event.key === "Escape") onClose(); + } + function handleBackButtonClose(event: KeyboardEvent) { + if (event.key === "Backspace") onClose(); + } + + if (isOpen && isPassiveModal) { + document.addEventListener("keydown", handleEscClose); + document.addEventListener("keydown", handleBackButtonClose); + } + return () => { + document.removeEventListener("keydown", handleEscClose); + document.removeEventListener("keydown", handleBackButtonClose); + }; + }, [isOpen, isPassiveModal, onClose]); + + if (!isOpen) return null; + return createPortal( + nonModal ? ( + + ) : ( + + + + ), + + document.body + ); +} + +type BaseProps = DialogProps & { + isActionModal: boolean; + nonModal: boolean; +}; + +function DialogBase({ dialogProps }: { dialogProps: BaseProps }) { + const { + modalType, + isSmall = false, + children, + actions, + sx, + style, + className, + isActionModal, + nonModal, + } = dialogProps; + + return ( + + {children} + {(isActionModal || nonModal) && !!actions ? ( // TODO: Action 부분도 unmount 되는 과정이 필요할 때가 있어 dialog props 에 넣지 않고 사용하는 방법 생각해보기. 현재는 node 가 null 이 아닐 때 렌더링 되도록 조건 수정. + {actions} + ) : null} + + ); +} + +export default Dialog; diff --git a/packages/design-system/src/components/Dialog/components/DialogAction.tsx b/packages/design-system/src/components/Dialog/components/DialogAction.tsx new file mode 100644 index 00000000..e9878251 --- /dev/null +++ b/packages/design-system/src/components/Dialog/components/DialogAction.tsx @@ -0,0 +1,36 @@ +import React from "react"; +import { styled } from "@mui/material/styles"; + +interface DialogActionProps { + children: React.ReactNode; + justifyContent?: React.CSSProperties["justifyContent"]; + sx?: React.CSSProperties; +} + +const StyledDialogActions = styled("div")({ + display: "flex", + flex: "0 0 auto", + alignItems: "center", + justifyContent: "flex-end", + gap: 8, +}); + +export function DialogAction(props: DialogActionProps) { + const { children, justifyContent, sx } = props; + + return ( + + {children} + + ); +} + +export default DialogAction; diff --git a/packages/design-system/src/components/Dialog/components/DialogContent.tsx b/packages/design-system/src/components/Dialog/components/DialogContent.tsx new file mode 100644 index 00000000..63ab5f01 --- /dev/null +++ b/packages/design-system/src/components/Dialog/components/DialogContent.tsx @@ -0,0 +1,28 @@ +import React from "react"; +import { styled } from "@mui/material/styles"; + +import type { SxProps } from "@mui/material/styles"; + +export interface DialogContentProps { + children: React.ReactNode; + sx?: SxProps; + style?: React.CSSProperties; +} + +const StyledDialogContent = styled("div")(({ theme }) => ({ + ...theme.typography.body2_14_regular, + flex: "1 1 auto", + overflowY: "scroll", +})); + +export function DialogContent(props: DialogContentProps) { + const { children, sx, style } = props; + + return ( + + {children} + + ); +} + +export default DialogContent; diff --git a/packages/design-system/src/components/Dialog/components/DialogTitle.tsx b/packages/design-system/src/components/Dialog/components/DialogTitle.tsx new file mode 100644 index 00000000..f356c41c --- /dev/null +++ b/packages/design-system/src/components/Dialog/components/DialogTitle.tsx @@ -0,0 +1,67 @@ +import React from "react"; +import { styled } from "@mui/material/styles"; +import { Close } from "@lunit/design-system-icons"; + +import Button from "../../Button"; +import Typography from "../../Typography"; + +import type { TypographyProps } from "@mui/material"; + +interface DialogTitleProps { + title: string; + icon?: React.ReactNode; + variant?: TypographyProps["variant"]; + onClose?: () => void; +} + +const StyledDialogTitle = styled("header")({ + display: "flex", + width: "100%", + flex: "0 0 auto", + alignItems: "center", + justifyContent: "flex-start", + gap: "8px", +}); + +const StyledDialogTitleIconWrapper = styled("div")({ + display: "flex", + justifyContent: "center", + width: "20px", + height: "20px", + position: "relative", + marginBottom: "1px", +}); + +export function DialogTitle(props: DialogTitleProps) { + const { variant = "headline5", title, icon, onClose } = props; + + return ( + + {icon && ( + + {icon} + + )} + + {title} + + {onClose && ( + + + + } + > + + + Lorem Ipsum is simply dummy text of the a printing and typesetting + industry + + + + ); + }, +}; + +export const NonModal: Story = { + name: "Type: non modal", + render: function NonModalRender() { + const { isOpen, open, close } = useDialog(); + + return ( + <> + + + + + + + + + + } + > + + + Lorem Ipsum is simply dummy text of the a printing and typesetting + industry + + + + ); + }, +}; + +export const SmallFalse: Story = { + name: "Option: small false", + render: function SmallFalseRender() { + const [target, setTarget] = useState(null); + + return ( +
+
setTarget(ref)} /> + + + + Lorem Ipsum is simply dummy text of the a printing and typesetting + industry + + +
+ ); + }, +}; + +export const WithTitleIcon: Story = { + name: "Option: title icon", + render: function WithTitleIconRender() { + const [target, setTarget] = useState(null); + + return ( +
+
setTarget(ref)} /> + + + + + } + > + } /> + + Lorem Ipsum is simply dummy text of the a printing and typesetting + industry + + +
+ ); + }, +}; + +export const WithCustomStyle: Story = { + name: "Option: custom style", + render: function WithCustomStyleRender() { + const [target, setTarget] = useState(null); + + return ( +
+
setTarget(ref)} /> + + + + Lorem Ipsum is simply dummy text of the a printing and typesetting + industry + + +
+ ); + }, +}; + +export const WithScroll: Story = { + name: "Option: with scroll", + render: function WithScrollRender() { + const [target, setTarget] = useState(null); + + return ( +
+
setTarget(ref)} /> + + + + + } + > + + + Lorem ipsum dolor sit amet consectetur, adipisicing elit. Quis, + suscipit at. Atque enim, hic architecto sequi libero deserunt + dolores omnis, cumque dignissimos ab animi. Recusandae saepe facere + error tempore quasi. Lorem ipsum dolor sit amet consectetur + adipisicing elit. Consectetur eius commodi deserunt reiciendis. + Officia veniam consequuntur doloribus debitis numquam ipsum autem, + eos repellendus eligendi esse voluptatum natus, cum optio? Unde! + Lorem ipsum dolor sit amet consectetur adipisicing elit. Quibusdam + praesentium incidunt tempora quam aut nulla corrupti ipsa voluptatem + vitae soluta ex officia, explicabo, voluptate porro. Eius mollitia + veritatis corporis neque. Lorem Ipsum is simply dummy text of the a + printing and typesetting industry Lorem ipsum dolor sit amet + consectetur Lorem ipsum dolor sit amet consectetur, adipisicing + elit. Quis, suscipit at. Atque enim, hic architecto sequi libero + deserunt dolores omnis, cumque dignissimos ab animi. Recusandae + saepe facere error tempore quasi. Lorem ipsum dolor sit amet + consectetur adipisicing elit. Consectetur eius commodi deserunt + reiciendis. Officia veniam consequuntur doloribus debitis numquam + ipsum autem, eos repellendus eligendi esse voluptatum natus, cum + optio? Unde! Lorem ipsum dolor sit amet consectetur adipisicing + elit. Quibusdam praesentium incidunt tempora quam aut nulla corrupti + ipsa voluptatem vitae soluta ex officia, explicabo, voluptate porro. + Eius mollitia veritatis corporis neque. Lorem Ipsum is simply dummy + text of the a printing and typesetting industry Lorem ipsum dolor + sit amet consectetur Lorem ipsum dolor sit amet consectetur, + adipisicing elit. Quis, suscipit at. Atque enim, hic architecto + sequi libero deserunt dolores omnis, cumque dignissimos ab animi. + Recusandae saepe facere error tempore quasi. Lorem ipsum dolor sit + amet consectetur adipisicing elit. Consectetur eius commodi deserunt + reiciendis. Officia veniam consequuntur doloribus debitis numquam + ipsum autem, eos repellendus eligendi esse voluptatum natus, cum + optio? Unde! Lorem ipsum dolor sit amet consectetur adipisicing + elit. Quibusdam praesentium incidunt tempora quam aut nulla corrupti + ipsa voluptatem vitae soluta ex officia, explicabo, voluptate porro. + Eius mollitia veritatis corporis neque. Lorem Ipsum is simply dummy + text of the a printing and typesetting industry Lorem ipsum dolor + sit amet consectetur + + +
+ ); + }, +}; From ebe1879e5345e9eb1f9a491cfdad7fd5cb11d7f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=96=91=ED=98=9C=EC=A7=84?= Date: Thu, 4 Apr 2024 17:05:52 +0900 Subject: [PATCH 03/19] feat: remove light2 class from DialogTitle --- .../src/components/Dialog/components/DialogTitle.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/design-system/src/components/Dialog/components/DialogTitle.tsx b/packages/design-system/src/components/Dialog/components/DialogTitle.tsx index f356c41c..2510e596 100644 --- a/packages/design-system/src/components/Dialog/components/DialogTitle.tsx +++ b/packages/design-system/src/components/Dialog/components/DialogTitle.tsx @@ -48,7 +48,6 @@ export function DialogTitle(props: DialogTitleProps) { {onClose && ( @@ -109,7 +112,8 @@ export const ActionModal: Story = { export const NonModal: Story = { name: "Type: non modal", - render: function NonModalRender() { + render: function NonModalRender(_Story, context) { + const classNameFromGlobal = context.globals.theme; const { isOpen, open, close } = useDialog(); return ( @@ -124,6 +128,7 @@ export const NonModal: Story = { Cancel @@ -157,13 +161,19 @@ export const NonModal: Story = { export const SmallFalse: Story = { name: "Option: small false", - render: function SmallFalseRender() { + render: function SmallFalseRender(_Story, context) { + const classNameFromGlobal = context.globals.theme; const [target, setTarget] = useState(null); return (
setTarget(ref)} /> - + Lorem Ipsum is simply dummy text of the a printing and typesetting @@ -177,13 +187,15 @@ export const SmallFalse: Story = { export const WithTitleIcon: Story = { name: "Option: title icon", - render: function WithTitleIconRender() { + render: function WithTitleIconRender(_Story, context) { + const classNameFromGlobal = context.globals.theme; const [target, setTarget] = useState(null); return (
setTarget(ref)} /> Cancel @@ -223,13 +234,15 @@ export const WithTitleIcon: Story = { export const WithCustomStyle: Story = { name: "Option: custom style", - render: function WithCustomStyleRender() { + render: function WithCustomStyleRender(_Story, context) { + const classNameFromGlobal = context.globals.theme; const [target, setTarget] = useState(null); return (
setTarget(ref)} /> (null); return (
setTarget(ref)} /> Cancel From bd2beaca993d41705985e70391074491cb89eb34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=96=91=ED=98=9C=EC=A7=84?= Date: Mon, 15 Apr 2024 14:14:04 +0900 Subject: [PATCH 06/19] feat: remove useDialog --- .../design-system/src/components/Dialog/index.ts | 1 - .../design-system/src/components/Dialog/useDialog.ts | 10 ---------- .../src/stories/components/Dialog/Dialog.stories.tsx | 12 +++++------- 3 files changed, 5 insertions(+), 18 deletions(-) delete mode 100644 packages/design-system/src/components/Dialog/useDialog.ts diff --git a/packages/design-system/src/components/Dialog/index.ts b/packages/design-system/src/components/Dialog/index.ts index bb4cdd67..c67a9189 100644 --- a/packages/design-system/src/components/Dialog/index.ts +++ b/packages/design-system/src/components/Dialog/index.ts @@ -1,4 +1,3 @@ export { default as Dialog } from "./Dialog"; export { default as DialogTitle } from "./components/DialogTitle"; export { default as DialogContent } from "./components/DialogContent"; -export { useDialog } from "./useDialog"; diff --git a/packages/design-system/src/components/Dialog/useDialog.ts b/packages/design-system/src/components/Dialog/useDialog.ts deleted file mode 100644 index e555f58a..00000000 --- a/packages/design-system/src/components/Dialog/useDialog.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { useState } from "react"; - -export const useDialog = () => { - const [isOpen, setIsOpen] = useState(false); - - const open = () => setIsOpen(true); - const close = () => setIsOpen(false); - - return { isOpen, open, close }; -}; diff --git a/packages/design-system/src/stories/components/Dialog/Dialog.stories.tsx b/packages/design-system/src/stories/components/Dialog/Dialog.stories.tsx index 4c2f997d..bc6c920e 100644 --- a/packages/design-system/src/stories/components/Dialog/Dialog.stories.tsx +++ b/packages/design-system/src/stories/components/Dialog/Dialog.stories.tsx @@ -3,12 +3,7 @@ import { Box, SvgIcon } from "@mui/material"; import Button from "../../../components/Button"; -import { - Dialog, - DialogTitle, - DialogContent, - useDialog, -} from "../../../components/Dialog"; +import { Dialog, DialogTitle, DialogContent } from "../../../components/Dialog"; import type { Meta, StoryObj } from "@storybook/react"; import type { SvgIconProps } from "@mui/material"; @@ -114,7 +109,10 @@ export const NonModal: Story = { name: "Type: non modal", render: function NonModalRender(_Story, context) { const classNameFromGlobal = context.globals.theme; - const { isOpen, open, close } = useDialog(); + const [isOpen, setIsOpen] = useState(false); + function open() { + setIsOpen(true); + } return ( <> From 1fb1676a855e00a9aa07b36eb941a0b47573ed89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=96=91=ED=98=9C=EC=A7=84?= Date: Mon, 15 Apr 2024 14:16:15 +0900 Subject: [PATCH 07/19] feat: export Dialog types --- packages/design-system/src/components/Dialog/index.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/design-system/src/components/Dialog/index.ts b/packages/design-system/src/components/Dialog/index.ts index c67a9189..fe3a5808 100644 --- a/packages/design-system/src/components/Dialog/index.ts +++ b/packages/design-system/src/components/Dialog/index.ts @@ -1,3 +1,12 @@ export { default as Dialog } from "./Dialog"; export { default as DialogTitle } from "./components/DialogTitle"; export { default as DialogContent } from "./components/DialogContent"; + +export type { + DialogPropsBase, + PassiveModalProps, + ActionModalProps, + ModalProps, + NonModalProps, + DialogProps, +} from "./Dialog"; From 573b39fda7953c88559fe358b81badfcb2daa09d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=96=91=ED=98=9C=EC=A7=84?= Date: Mon, 15 Apr 2024 14:33:04 +0900 Subject: [PATCH 08/19] feat: remove unused Modal component & story --- .../design-system/src/components/Modal/Modal.tsx | 8 -------- .../design-system/src/components/Modal/index.ts | 1 - packages/design-system/src/index.ts | 1 - .../stories/components/Modal/Modal.stories.tsx | 15 --------------- 4 files changed, 25 deletions(-) delete mode 100644 packages/design-system/src/components/Modal/Modal.tsx delete mode 100644 packages/design-system/src/components/Modal/index.ts delete mode 100644 packages/design-system/src/stories/components/Modal/Modal.stories.tsx diff --git a/packages/design-system/src/components/Modal/Modal.tsx b/packages/design-system/src/components/Modal/Modal.tsx deleted file mode 100644 index e2d78b69..00000000 --- a/packages/design-system/src/components/Modal/Modal.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import React from "react"; -import { Box } from "@mui/material"; - -const Modal = () => { - return Modal; -}; - -export default Modal; diff --git a/packages/design-system/src/components/Modal/index.ts b/packages/design-system/src/components/Modal/index.ts deleted file mode 100644 index 09b91f72..00000000 --- a/packages/design-system/src/components/Modal/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./Modal"; diff --git a/packages/design-system/src/index.ts b/packages/design-system/src/index.ts index 1c7b84fa..09001d49 100644 --- a/packages/design-system/src/index.ts +++ b/packages/design-system/src/index.ts @@ -9,7 +9,6 @@ export { default as DataTable } from "./components/DataTable"; export { default as DatePicker } from "./components/DatePicker"; export { default as Dropdown } from "./components/Dropdown"; export { default as FormLabel } from "./components/FormLabel"; -export { default as Modal } from "./components/Modal"; export { default as Radio } from "./components/Radio"; export { default as RadioGroup } from "./components/RadioGroup"; export { default as TextField } from "./components/TextField"; diff --git a/packages/design-system/src/stories/components/Modal/Modal.stories.tsx b/packages/design-system/src/stories/components/Modal/Modal.stories.tsx deleted file mode 100644 index 5162a2bc..00000000 --- a/packages/design-system/src/stories/components/Modal/Modal.stories.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from "react"; -import { StoryFn, Meta } from "@storybook/react"; - -import Modal from "@/components/Modal"; - -export default { - title: "Components/Modal", - component: Modal, -} as Meta; - -const Template: StoryFn = () => ; - -export const LunitModal = { - render: Template, -}; From 6eadc6d8704fec7ed839ff7ccdf42b325a71cd25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=96=91=ED=98=9C=EC=A7=84?= Date: Mon, 15 Apr 2024 14:42:19 +0900 Subject: [PATCH 09/19] feat: remove onClose from dialog title on storybook --- .../src/stories/components/Dialog/Dialog.stories.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/design-system/src/stories/components/Dialog/Dialog.stories.tsx b/packages/design-system/src/stories/components/Dialog/Dialog.stories.tsx index bc6c920e..8800fc02 100644 --- a/packages/design-system/src/stories/components/Dialog/Dialog.stories.tsx +++ b/packages/design-system/src/stories/components/Dialog/Dialog.stories.tsx @@ -94,7 +94,7 @@ export const ActionModal: Story = { } > - + Lorem Ipsum is simply dummy text of the a printing and typesetting industry @@ -114,6 +114,10 @@ export const NonModal: Story = { setIsOpen(true); } + function close() { + setIsOpen(false); + } + return ( <> @@ -146,7 +150,7 @@ export const NonModal: Story = { } > - + Lorem Ipsum is simply dummy text of the a printing and typesetting industry From 09d3dea0b336c8812a628b670413b9893930e822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=96=91=ED=98=9C=EC=A7=84?= Date: Mon, 15 Apr 2024 15:36:44 +0900 Subject: [PATCH 10/19] feat: change NonModal type as nonModal instead of undefined --- packages/design-system/src/components/Dialog/Dialog.tsx | 6 +++--- .../src/stories/components/Dialog/Dialog.stories.tsx | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/design-system/src/components/Dialog/Dialog.tsx b/packages/design-system/src/components/Dialog/Dialog.tsx index d3e626b9..4300a5ee 100644 --- a/packages/design-system/src/components/Dialog/Dialog.tsx +++ b/packages/design-system/src/components/Dialog/Dialog.tsx @@ -9,7 +9,7 @@ import type { SxProps } from "@mui/material/styles"; export interface DialogPropsBase { isOpen: boolean; isSmall?: boolean; - modalType?: "passive" | "action"; + modalType: "passive" | "action" | "nonModal"; onClose(): void; children: React.ReactNode; sx?: SxProps; @@ -31,7 +31,7 @@ export interface ActionModalProps extends DialogPropsBase { export type ModalProps = PassiveModalProps | ActionModalProps; export interface NonModalProps extends DialogPropsBase { - modalType?: undefined; + modalType: "nonModal"; actions: React.ReactNode; } @@ -40,7 +40,7 @@ export type DialogProps = ModalProps | NonModalProps; function Dialog(props: DialogProps) { const { isOpen, modalType, onClose } = props; - const nonModal = !modalType; + const nonModal = modalType === "nonModal"; const isActionModal = modalType === "action"; const isPassiveModal = modalType === "passive"; diff --git a/packages/design-system/src/stories/components/Dialog/Dialog.stories.tsx b/packages/design-system/src/stories/components/Dialog/Dialog.stories.tsx index 8800fc02..156627e5 100644 --- a/packages/design-system/src/stories/components/Dialog/Dialog.stories.tsx +++ b/packages/design-system/src/stories/components/Dialog/Dialog.stories.tsx @@ -131,6 +131,7 @@ export const NonModal: Story = { Date: Mon, 15 Apr 2024 15:43:13 +0900 Subject: [PATCH 11/19] fix: change conditional rendering by modal type --- packages/design-system/src/components/Dialog/Dialog.styled.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/design-system/src/components/Dialog/Dialog.styled.ts b/packages/design-system/src/components/Dialog/Dialog.styled.ts index 3ce577da..c1b858e0 100644 --- a/packages/design-system/src/components/Dialog/Dialog.styled.ts +++ b/packages/design-system/src/components/Dialog/Dialog.styled.ts @@ -99,7 +99,7 @@ export const StyledDialog = styled("div")( color: theme.palette.lunit_token.core.text_normal, ...DIALOG_WRAPPER_STYLE[isSmall ? "small" : "medium"], - ...DIALOG_WRAPPER_STYLE[modalType ? "modal" : "nonModal"], + ...DIALOG_WRAPPER_STYLE[modalType === "nonModal" ? "nonModal" : "modal"], "& #dialog-title": { ...DIALOG_TITLE_STYLE[isSmall ? "small" : "medium"], From 627303dd33127556f543446ce8cc42adc298ecc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=96=91=ED=98=9C=EC=A7=84?= Date: Mon, 22 Apr 2024 15:22:04 +0900 Subject: [PATCH 12/19] feat: Change Dialog API --- .../src/components/Dialog/Dialog.styled.ts | 30 +++- .../src/components/Dialog/Dialog.tsx | 145 +++++++++++++----- .../Dialog/components/DialogTitle.tsx | 66 -------- .../src/components/Dialog/index.ts | 8 +- .../components/Dialog/Dialog.stories.tsx | 51 +++--- 5 files changed, 155 insertions(+), 145 deletions(-) delete mode 100644 packages/design-system/src/components/Dialog/components/DialogTitle.tsx diff --git a/packages/design-system/src/components/Dialog/Dialog.styled.ts b/packages/design-system/src/components/Dialog/Dialog.styled.ts index c1b858e0..4f7e15c0 100644 --- a/packages/design-system/src/components/Dialog/Dialog.styled.ts +++ b/packages/design-system/src/components/Dialog/Dialog.styled.ts @@ -1,13 +1,13 @@ import { styled } from "@mui/material/styles"; -import type { DialogPropsBase } from "./Dialog"; +import type { DialogTypeBase } from "./Dialog"; import type { CSSObject } from "@mui/material/styles"; export interface DialogElementStyle { [key: string]: CSSObject; } -export type DialogStyle = Pick; +export type DialogStyle = Pick; const DIALOG_WRAPPER_STYLE: DialogElementStyle = { small: { @@ -88,7 +88,7 @@ export const StyledBackdrop = styled("div")({ }); export const StyledDialog = styled("div")( - ({ theme, isSmall, modalType }) => ({ + ({ theme, isSmall, isModal, type }) => ({ zIndex: 1001, maxHeight: "80vh", display: "flex", @@ -99,7 +99,7 @@ export const StyledDialog = styled("div")( color: theme.palette.lunit_token.core.text_normal, ...DIALOG_WRAPPER_STYLE[isSmall ? "small" : "medium"], - ...DIALOG_WRAPPER_STYLE[modalType === "nonModal" ? "nonModal" : "modal"], + ...DIALOG_WRAPPER_STYLE[isModal ? "modal" : "nonModal"], "& #dialog-title": { ...DIALOG_TITLE_STYLE[isSmall ? "small" : "medium"], @@ -107,11 +107,11 @@ export const StyledDialog = styled("div")( "& #dialog-content": { ...DIALOG_CONTENT_STYLE[ - isSmall && modalType !== "passive" + isSmall && type !== "passive" ? "smallAction" : isSmall ? "small" - : !isSmall && modalType !== "passive" + : !isSmall && type !== "passive" ? "mediumAction" : "medium" ], @@ -139,3 +139,21 @@ export const StyledDialog = styled("div")( }, }) ); + +export const StyledDialogTitle = styled("header")({ + display: "flex", + width: "100%", + flex: "0 0 auto", + alignItems: "center", + justifyContent: "flex-start", + gap: "8px", +}); + +export const StyledDialogTitleIconWrapper = styled("div")({ + display: "flex", + justifyContent: "center", + width: "20px", + height: "20px", + position: "relative", + marginBottom: "1px", +}); diff --git a/packages/design-system/src/components/Dialog/Dialog.tsx b/packages/design-system/src/components/Dialog/Dialog.tsx index 4300a5ee..58d5d2a2 100644 --- a/packages/design-system/src/components/Dialog/Dialog.tsx +++ b/packages/design-system/src/components/Dialog/Dialog.tsx @@ -1,59 +1,98 @@ import React, { useEffect } from "react"; import { createPortal } from "react-dom"; +import { Close } from "@lunit/design-system-icons"; import { DialogAction } from "./components/DialogAction"; -import { StyledBackdrop, StyledDialog } from "./Dialog.styled"; +import { + StyledBackdrop, + StyledDialog, + StyledDialogTitle, + StyledDialogTitleIconWrapper, +} from "./Dialog.styled"; +import Button from "../Button"; +import Typography from "../Typography"; import type { SxProps } from "@mui/material/styles"; +import type { TypographyProps } from "@mui/material"; -export interface DialogPropsBase { +export interface DialogBase { isOpen: boolean; - isSmall?: boolean; - modalType: "passive" | "action" | "nonModal"; onClose(): void; + title: string; + titleIcon?: React.ReactNode; + titleVariant?: TypographyProps["variant"]; children: React.ReactNode; + isModal?: boolean; // default true + isSmall?: boolean; // default true sx?: SxProps; style?: React.CSSProperties; className?: string; } -export interface PassiveModalProps extends DialogPropsBase { - modalType: "passive"; +export interface DialogTypeBase extends DialogBase { + type?: "passive" | "action"; // default passive + actions?: React.ReactNode; + enableBackButtonClose?: boolean; + enableBackdropClose?: boolean; +} +export interface PassiveDialogType extends DialogTypeBase { + type: "passive"; actions?: undefined; + enableBackButtonClose?: true; + enableBackdropClose?: true; } - -export interface ActionModalProps extends DialogPropsBase { - modalType: "action"; +export interface ActionDialogType extends DialogTypeBase { + type: "action"; actions: React.ReactNode; + enableBackButtonClose?: boolean; enableBackdropClose?: boolean; } +export interface PassiveModalProps extends PassiveDialogType { + isModal?: true; +} +export interface ActionModalProps extends ActionDialogType { + isModal?: true; +} export type ModalProps = PassiveModalProps | ActionModalProps; -export interface NonModalProps extends DialogPropsBase { - modalType: "nonModal"; - actions: React.ReactNode; +export interface PassiveNonModalProps extends PassiveDialogType { + isModal?: false; +} +export interface ActionNonModalProps extends ActionDialogType { + isModal?: false; + enableBackdropClose?: false; } +export type NonModalProps = PassiveNonModalProps | ActionNonModalProps; export type DialogProps = ModalProps | NonModalProps; function Dialog(props: DialogProps) { - const { isOpen, modalType, onClose } = props; + const { isOpen, type, isModal = true, onClose } = props; - const nonModal = modalType === "nonModal"; - const isActionModal = modalType === "action"; - const isPassiveModal = modalType === "passive"; + const isActionModal = type === "action" && isModal; + const isPassiveModal = type === "passive" && isModal; + const isActionNonModal = type === "action" && !isModal; function handleBackdropClose(e: React.MouseEvent) { - if (e.target !== e.currentTarget) return; - const enableBackdropClose = + const isClosable = isPassiveModal || (isActionModal && props.enableBackdropClose); - if (!enableBackdropClose) return; + if (!isClosable) return; + if (e.target !== e.currentTarget) return; + onClose(); } useEffect(() => { + const isClosable = + isOpen && + (isPassiveModal || + (isActionModal && props.enableBackdropClose) || + (isActionNonModal && props.enableBackButtonClose)); + + if (!isClosable) return; + function handleEscClose(event: KeyboardEvent) { if (event.key === "Escape") onClose(); } @@ -61,10 +100,9 @@ function Dialog(props: DialogProps) { if (event.key === "Backspace") onClose(); } - if (isOpen && isPassiveModal) { - document.addEventListener("keydown", handleEscClose); - document.addEventListener("keydown", handleBackButtonClose); - } + document.addEventListener("keydown", handleEscClose); + document.addEventListener("keydown", handleBackButtonClose); + return () => { document.removeEventListener("keydown", handleEscClose); document.removeEventListener("keydown", handleBackButtonClose); @@ -73,14 +111,14 @@ function Dialog(props: DialogProps) { if (!isOpen) return null; return createPortal( - nonModal ? ( - + !isModal ? ( + ) : ( - + ), @@ -88,22 +126,20 @@ function Dialog(props: DialogProps) { ); } -type BaseProps = DialogProps & { - isActionModal: boolean; - nonModal: boolean; -}; - -function DialogBase({ dialogProps }: { dialogProps: BaseProps }) { +function DialogBase({ dialogProps }: { dialogProps: DialogTypeBase }) { const { - modalType, - isSmall = false, + isModal = true, + onClose, + title, + titleIcon, + titleVariant = "headline5", children, actions, + type, + isSmall = false, sx, style, className, - isActionModal, - nonModal, } = dialogProps; return ( @@ -111,17 +147,44 @@ function DialogBase({ dialogProps }: { dialogProps: BaseProps }) { role="dialog" aria-labelledby="dialog-title" isSmall={isSmall} - modalType={modalType} + isModal={isModal} + type={type} sx={{ ...sx, }} style={style} - className={`light1 dialog ${className ?? ""}`} + className={`dialog ${className ?? ""}`} > + + {titleIcon && ( + + {titleIcon} + + )} + + {title} + + {type === "passive" && ( +
); @@ -83,10 +80,8 @@ export const ActionModal: Story = { } > - - Lorem Ipsum is simply dummy text of the a printing and typesetting - industry - + Lorem Ipsum is simply dummy text of the a printing and typesetting + industry
); @@ -141,10 +136,8 @@ export const NonModal: Story = { } > - - Lorem Ipsum is simply dummy text of the a printing and typesetting - industry - + Lorem Ipsum is simply dummy text of the a printing and typesetting + industry
); @@ -168,10 +161,8 @@ export const SmallFalse: Story = { title="Title area" isSmall={false} > - - Lorem Ipsum is simply dummy text of the a printing and typesetting - industry - + Lorem Ipsum is simply dummy text of the a printing and typesetting + industry
); @@ -216,10 +207,8 @@ export const WithTitleIcon: Story = { } > - - Lorem Ipsum is simply dummy text of the a printing and typesetting - industry - + Lorem Ipsum is simply dummy text of the a printing and typesetting + industry
); @@ -250,10 +239,8 @@ export const WithCustomStyle: Story = { }, }} > - - Lorem Ipsum is simply dummy text of the a printing and typesetting - industry - + Lorem Ipsum is simply dummy text of the a printing and typesetting + industry
); @@ -297,45 +284,42 @@ export const WithScroll: Story = { } > - - Lorem ipsum dolor sit amet consectetur, adipisicing elit. Quis, - suscipit at. Atque enim, hic architecto sequi libero deserunt - dolores omnis, cumque dignissimos ab animi. Recusandae saepe facere - error tempore quasi. Lorem ipsum dolor sit amet consectetur - adipisicing elit. Consectetur eius commodi deserunt reiciendis. - Officia veniam consequuntur doloribus debitis numquam ipsum autem, - eos repellendus eligendi esse voluptatum natus, cum optio? Unde! - Lorem ipsum dolor sit amet consectetur adipisicing elit. Quibusdam - praesentium incidunt tempora quam aut nulla corrupti ipsa voluptatem - vitae soluta ex officia, explicabo, voluptate porro. Eius mollitia - veritatis corporis neque. Lorem Ipsum is simply dummy text of the a - printing and typesetting industry Lorem ipsum dolor sit amet - consectetur Lorem ipsum dolor sit amet consectetur, adipisicing - elit. Quis, suscipit at. Atque enim, hic architecto sequi libero - deserunt dolores omnis, cumque dignissimos ab animi. Recusandae - saepe facere error tempore quasi. Lorem ipsum dolor sit amet - consectetur adipisicing elit. Consectetur eius commodi deserunt - reiciendis. Officia veniam consequuntur doloribus debitis numquam - ipsum autem, eos repellendus eligendi esse voluptatum natus, cum - optio? Unde! Lorem ipsum dolor sit amet consectetur adipisicing - elit. Quibusdam praesentium incidunt tempora quam aut nulla corrupti - ipsa voluptatem vitae soluta ex officia, explicabo, voluptate porro. - Eius mollitia veritatis corporis neque. Lorem Ipsum is simply dummy - text of the a printing and typesetting industry Lorem ipsum dolor - sit amet consectetur Lorem ipsum dolor sit amet consectetur, - adipisicing elit. Quis, suscipit at. Atque enim, hic architecto - sequi libero deserunt dolores omnis, cumque dignissimos ab animi. - Recusandae saepe facere error tempore quasi. Lorem ipsum dolor sit - amet consectetur adipisicing elit. Consectetur eius commodi deserunt - reiciendis. Officia veniam consequuntur doloribus debitis numquam - ipsum autem, eos repellendus eligendi esse voluptatum natus, cum - optio? Unde! Lorem ipsum dolor sit amet consectetur adipisicing - elit. Quibusdam praesentium incidunt tempora quam aut nulla corrupti - ipsa voluptatem vitae soluta ex officia, explicabo, voluptate porro. - Eius mollitia veritatis corporis neque. Lorem Ipsum is simply dummy - text of the a printing and typesetting industry Lorem ipsum dolor - sit amet consectetur - + Lorem ipsum dolor sit amet consectetur, adipisicing elit. Quis, + suscipit at. Atque enim, hic architecto sequi libero deserunt dolores + omnis, cumque dignissimos ab animi. Recusandae saepe facere error + tempore quasi. Lorem ipsum dolor sit amet consectetur adipisicing + elit. Consectetur eius commodi deserunt reiciendis. Officia veniam + consequuntur doloribus debitis numquam ipsum autem, eos repellendus + eligendi esse voluptatum natus, cum optio? Unde! Lorem ipsum dolor sit + amet consectetur adipisicing elit. Quibusdam praesentium incidunt + tempora quam aut nulla corrupti ipsa voluptatem vitae soluta ex + officia, explicabo, voluptate porro. Eius mollitia veritatis corporis + neque. Lorem Ipsum is simply dummy text of the a printing and + typesetting industry Lorem ipsum dolor sit amet consectetur Lorem + ipsum dolor sit amet consectetur, adipisicing elit. Quis, suscipit at. + Atque enim, hic architecto sequi libero deserunt dolores omnis, cumque + dignissimos ab animi. Recusandae saepe facere error tempore quasi. + Lorem ipsum dolor sit amet consectetur adipisicing elit. Consectetur + eius commodi deserunt reiciendis. Officia veniam consequuntur + doloribus debitis numquam ipsum autem, eos repellendus eligendi esse + voluptatum natus, cum optio? Unde! Lorem ipsum dolor sit amet + consectetur adipisicing elit. Quibusdam praesentium incidunt tempora + quam aut nulla corrupti ipsa voluptatem vitae soluta ex officia, + explicabo, voluptate porro. Eius mollitia veritatis corporis neque. + Lorem Ipsum is simply dummy text of the a printing and typesetting + industry Lorem ipsum dolor sit amet consectetur Lorem ipsum dolor sit + amet consectetur, adipisicing elit. Quis, suscipit at. Atque enim, hic + architecto sequi libero deserunt dolores omnis, cumque dignissimos ab + animi. Recusandae saepe facere error tempore quasi. Lorem ipsum dolor + sit amet consectetur adipisicing elit. Consectetur eius commodi + deserunt reiciendis. Officia veniam consequuntur doloribus debitis + numquam ipsum autem, eos repellendus eligendi esse voluptatum natus, + cum optio? Unde! Lorem ipsum dolor sit amet consectetur adipisicing + elit. Quibusdam praesentium incidunt tempora quam aut nulla corrupti + ipsa voluptatem vitae soluta ex officia, explicabo, voluptate porro. + Eius mollitia veritatis corporis neque. Lorem Ipsum is simply dummy + text of the a printing and typesetting industry Lorem ipsum dolor sit + amet consectetur
); From 2187b5b4adf1d65f170a4323da7805e165cba105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=96=91=ED=98=9C=EC=A7=84?= Date: Wed, 24 Apr 2024 14:59:19 +0900 Subject: [PATCH 17/19] feat: remove DialogTypeBase --- .../src/components/Dialog/Dialog.styled.ts | 4 ++-- .../src/components/Dialog/Dialog.tsx | 18 ++++++++---------- .../src/components/Dialog/index.ts | 1 - 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/packages/design-system/src/components/Dialog/Dialog.styled.ts b/packages/design-system/src/components/Dialog/Dialog.styled.ts index 86b0f187..3d82152a 100644 --- a/packages/design-system/src/components/Dialog/Dialog.styled.ts +++ b/packages/design-system/src/components/Dialog/Dialog.styled.ts @@ -1,13 +1,13 @@ import { styled } from "@mui/material/styles"; -import type { DialogTypeBase } from "./Dialog"; +import type { DialogBase } from "./Dialog"; import type { CSSObject } from "@mui/material/styles"; export interface DialogElementStyle { [key: string]: CSSObject; } -export type DialogStyle = Pick; +export type DialogStyle = Pick; const DIALOG_WRAPPER_STYLE: DialogElementStyle = { small: { diff --git a/packages/design-system/src/components/Dialog/Dialog.tsx b/packages/design-system/src/components/Dialog/Dialog.tsx index fd6beb3f..eb36be8c 100644 --- a/packages/design-system/src/components/Dialog/Dialog.tsx +++ b/packages/design-system/src/components/Dialog/Dialog.tsx @@ -19,30 +19,28 @@ import type { TypographyProps } from "@mui/material"; export interface DialogBase { isOpen: boolean; onClose(): void; + type?: "passive" | "action"; // default passive + nonModal?: boolean; // default false title: string; titleIcon?: React.ReactNode; titleVariant?: TypographyProps["variant"]; children: React.ReactNode; - nonModal?: boolean; // default false + actions?: React.ReactNode; + enableBackButtonClose?: boolean; + enableBackdropClose?: boolean; isSmall?: boolean; // default true sx?: SxProps; style?: React.CSSProperties; className?: string; } -export interface DialogTypeBase extends DialogBase { - type?: "passive" | "action"; // default passive - actions?: React.ReactNode; - enableBackButtonClose?: boolean; - enableBackdropClose?: boolean; -} -export interface PassiveDialogType extends DialogTypeBase { +export interface PassiveDialogType extends DialogBase { type: "passive"; actions?: undefined; enableBackButtonClose?: true; enableBackdropClose?: true; } -export interface ActionDialogType extends DialogTypeBase { +export interface ActionDialogType extends DialogBase { type: "action"; actions: React.ReactNode; enableBackButtonClose?: boolean; @@ -127,7 +125,7 @@ function Dialog(props: DialogProps) { ); } -function DialogBase({ dialogProps }: { dialogProps: DialogTypeBase }) { +function DialogBase({ dialogProps }: { dialogProps: DialogBase }) { const { nonModal = false, onClose, diff --git a/packages/design-system/src/components/Dialog/index.ts b/packages/design-system/src/components/Dialog/index.ts index 881132c0..067ba5f5 100644 --- a/packages/design-system/src/components/Dialog/index.ts +++ b/packages/design-system/src/components/Dialog/index.ts @@ -2,7 +2,6 @@ export { default as Dialog } from "./Dialog"; export type { DialogBase, - DialogTypeBase, PassiveDialogType, ActionDialogType, PassiveModalProps, From ab83a02e4c40f3b5e015249f92194aba8f1b5ebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=96=91=ED=98=9C=EC=A7=84?= Date: Wed, 24 Apr 2024 15:04:56 +0900 Subject: [PATCH 18/19] feat: change isSmall prop to size --- .../src/components/Dialog/Dialog.styled.ts | 18 +++++++++--------- .../src/components/Dialog/Dialog.tsx | 6 +++--- .../components/Dialog/Dialog.stories.tsx | 8 +------- 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/packages/design-system/src/components/Dialog/Dialog.styled.ts b/packages/design-system/src/components/Dialog/Dialog.styled.ts index 3d82152a..feb49b01 100644 --- a/packages/design-system/src/components/Dialog/Dialog.styled.ts +++ b/packages/design-system/src/components/Dialog/Dialog.styled.ts @@ -7,7 +7,7 @@ export interface DialogElementStyle { [key: string]: CSSObject; } -export type DialogStyle = Pick; +export type DialogStyle = Pick; const DIALOG_WRAPPER_STYLE: DialogElementStyle = { small: { @@ -88,7 +88,7 @@ export const StyledBackdrop = styled("div")({ }); export const StyledDialog = styled("div")( - ({ theme, isSmall, nonModal, type }) => ({ + ({ theme, size, nonModal, type }) => ({ zIndex: 1001, maxHeight: "80vh", display: "flex", @@ -98,27 +98,27 @@ export const StyledDialog = styled("div")( backgroundColor: theme.palette.lunit_token.core.bg_03, color: theme.palette.lunit_token.core.text_normal, - ...DIALOG_WRAPPER_STYLE[isSmall ? "small" : "medium"], + ...DIALOG_WRAPPER_STYLE[size === "small" ? "small" : "medium"], ...DIALOG_WRAPPER_STYLE[nonModal ? "nonModal" : "modal"], "& #dialog-title": { - ...DIALOG_TITLE_STYLE[isSmall ? "small" : "medium"], + ...DIALOG_TITLE_STYLE[size === "small" ? "small" : "medium"], }, "& #dialog-content": { ...DIALOG_CONTENT_STYLE[ - isSmall && type !== "passive" + size === "small" && type !== "passive" ? "smallAction" - : isSmall + : size === "small" ? "small" - : !isSmall && type !== "passive" + : size === "medium" && type !== "passive" ? "mediumAction" : "medium" ], scrollbarGutter: "stable", "::-webkit-scrollbar": { - width: isSmall ? "10px" : "14px", + width: size === "small" ? "10px" : "14px", }, "::webkit-scrollbar-track": { background: "transparent", @@ -135,7 +135,7 @@ export const StyledDialog = styled("div")( }, "& #dialog-action": { - ...DIALOG_ACTION_STYLE[isSmall ? "small" : "medium"], + ...DIALOG_ACTION_STYLE[size === "small" ? "small" : "medium"], }, }) ); diff --git a/packages/design-system/src/components/Dialog/Dialog.tsx b/packages/design-system/src/components/Dialog/Dialog.tsx index eb36be8c..c64cbd8b 100644 --- a/packages/design-system/src/components/Dialog/Dialog.tsx +++ b/packages/design-system/src/components/Dialog/Dialog.tsx @@ -28,7 +28,7 @@ export interface DialogBase { actions?: React.ReactNode; enableBackButtonClose?: boolean; enableBackdropClose?: boolean; - isSmall?: boolean; // default true + size?: "small" | "medium"; // default "small" sx?: SxProps; style?: React.CSSProperties; className?: string; @@ -135,7 +135,7 @@ function DialogBase({ dialogProps }: { dialogProps: DialogBase }) { children, actions, type, - isSmall = false, + size = "small", sx, style, className, @@ -145,7 +145,7 @@ function DialogBase({ dialogProps }: { dialogProps: DialogBase }) { Lorem Ipsum is simply dummy text of the a printing and typesetting industry @@ -61,7 +60,6 @@ export const ActionModal: Story = { className={classNameFromGlobal} isOpen={Boolean(target)} onClose={close} - isSmall type="action" title="Title area" actions={ @@ -117,7 +115,6 @@ export const NonModal: Story = { isOpen={isOpen} nonModal type="action" - isSmall onClose={close} title="Title area" actions={ @@ -159,7 +156,7 @@ export const SmallFalse: Story = { type="passive" onClose={close} title="Title area" - isSmall={false} + size="medium" > Lorem Ipsum is simply dummy text of the a printing and typesetting industry @@ -181,7 +178,6 @@ export const WithTitleIcon: Story = { Date: Fri, 26 Apr 2024 12:59:38 +0900 Subject: [PATCH 19/19] feat: change export and import of Dialog --- packages/design-system/src/components/Dialog/index.ts | 2 +- packages/design-system/src/index.ts | 1 + .../src/stories/components/Dialog/Dialog.stories.tsx | 5 ++--- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/design-system/src/components/Dialog/index.ts b/packages/design-system/src/components/Dialog/index.ts index 067ba5f5..3ac1297a 100644 --- a/packages/design-system/src/components/Dialog/index.ts +++ b/packages/design-system/src/components/Dialog/index.ts @@ -1,4 +1,4 @@ -export { default as Dialog } from "./Dialog"; +export { default } from "./Dialog"; export type { DialogBase, diff --git a/packages/design-system/src/index.ts b/packages/design-system/src/index.ts index 09001d49..bd61f549 100644 --- a/packages/design-system/src/index.ts +++ b/packages/design-system/src/index.ts @@ -5,6 +5,7 @@ export { default as Alert } from "./components/Alert"; export { default as Button } from "./components/Button"; export { default as Chip } from "./components/Chip"; export { default as Checkbox } from "./components/Checkbox"; +export { default as Dialog } from "./components/Dialog"; export { default as DataTable } from "./components/DataTable"; export { default as DatePicker } from "./components/DatePicker"; export { default as Dropdown } from "./components/Dropdown"; diff --git a/packages/design-system/src/stories/components/Dialog/Dialog.stories.tsx b/packages/design-system/src/stories/components/Dialog/Dialog.stories.tsx index 110dd862..cfff6852 100644 --- a/packages/design-system/src/stories/components/Dialog/Dialog.stories.tsx +++ b/packages/design-system/src/stories/components/Dialog/Dialog.stories.tsx @@ -2,9 +2,8 @@ import React, { useState } from "react"; import { Box } from "@mui/material"; import Error from "@lunit/design-system-icons/Error"; -import Button from "../../../components/Button"; - -import { Dialog } from "../../../components/Dialog"; +import Button from "@/components/Button"; +import Dialog from "@/components/Dialog"; import type { Meta, StoryObj } from "@storybook/react";