From 188449f3b47b8dfe68b0d31c7ec8a68e168fc668 Mon Sep 17 00:00:00 2001 From: Touha Zohair <39002455+touha98@users.noreply.github.com> Date: Sat, 6 Jan 2024 03:50:07 +0600 Subject: [PATCH] feat: Dialog Component (#886) * basic dialog component --------- Co-authored-by: severinlandolt Co-authored-by: christopherkindl <53372002+christopherkindl@users.noreply.github.com> --- .../layout-elements/Dialog/Dialog.tsx | 54 +++++++++++++++++++ .../layout-elements/Dialog/DialogPanel.tsx | 49 +++++++++++++++++ .../layout-elements/Dialog/index.ts | 2 + src/components/layout-elements/index.ts | 1 + .../layout-elements/Dialog.stories.tsx | 21 ++++++++ .../layout-elements/helpers/SimpleDialog.tsx | 28 ++++++++++ src/tests/layout-elements/Dialog.test.tsx | 19 +++++++ 7 files changed, 174 insertions(+) create mode 100644 src/components/layout-elements/Dialog/Dialog.tsx create mode 100644 src/components/layout-elements/Dialog/DialogPanel.tsx create mode 100644 src/components/layout-elements/Dialog/index.ts create mode 100644 src/stories/layout-elements/Dialog.stories.tsx create mode 100644 src/stories/layout-elements/helpers/SimpleDialog.tsx create mode 100644 src/tests/layout-elements/Dialog.test.tsx diff --git a/src/components/layout-elements/Dialog/Dialog.tsx b/src/components/layout-elements/Dialog/Dialog.tsx new file mode 100644 index 000000000..28297ab97 --- /dev/null +++ b/src/components/layout-elements/Dialog/Dialog.tsx @@ -0,0 +1,54 @@ +import React from "react"; +import { Dialog as HeadlessuiDialog, Transition } from "@headlessui/react"; +import { makeClassName, tremorTwMerge } from "lib"; + +const makeDisplayClassName = makeClassName("dialog"); + +type Without = { [P in Exclude]?: never }; +type XOR = T | U extends object ? (Without & U) | (Without & T) : T | U; + +export type DialogProps = React.HTMLAttributes & { + open: boolean; + onClose: (val: boolean) => void; + overlayClassName?: string; +} & XOR<{ unmount?: boolean }, { static?: boolean }>; + +const Dialog = React.forwardRef((props, ref) => { + const { children, className, overlayClassName, ...other } = props; + + return ( + + + +
+
+ +
+
{children}
+
+
+
+ ); +}); + +Dialog.displayName = "Dialog"; + +export default Dialog; diff --git a/src/components/layout-elements/Dialog/DialogPanel.tsx b/src/components/layout-elements/Dialog/DialogPanel.tsx new file mode 100644 index 000000000..02636c303 --- /dev/null +++ b/src/components/layout-elements/Dialog/DialogPanel.tsx @@ -0,0 +1,49 @@ +import React from "react"; +import { Dialog as HeadlessuiDialog, Transition } from "@headlessui/react"; +import { makeClassName, spacing, tremorTwMerge } from "lib"; +import { RootStylesContext } from "contexts"; + +const makeDisplayClassName = makeClassName("dialog"); + +export type DialogPanelProps = React.HTMLAttributes; + +const DialogPanel = React.forwardRef((props, ref) => { + const { children, className, ...other } = props; + const rootStyles = + React.useContext(RootStylesContext) ?? + tremorTwMerge(spacing.threeXl.paddingAll, "rounded-tremor-default"); + + return ( + + + {children} + + + ); +}); + +DialogPanel.displayName = "DialogPanel"; + +export default DialogPanel; diff --git a/src/components/layout-elements/Dialog/index.ts b/src/components/layout-elements/Dialog/index.ts new file mode 100644 index 000000000..945dcab0a --- /dev/null +++ b/src/components/layout-elements/Dialog/index.ts @@ -0,0 +1,2 @@ +export { default as Dialog, type DialogProps } from "./Dialog"; +export { default as DialogPanel, type DialogPanelProps } from "./DialogPanel"; diff --git a/src/components/layout-elements/index.ts b/src/components/layout-elements/index.ts index 3dcdb29c7..c92f948a4 100644 --- a/src/components/layout-elements/index.ts +++ b/src/components/layout-elements/index.ts @@ -3,3 +3,4 @@ export * from "./Card"; export * from "./Divider"; export * from "./Flex"; export * from "./Grid"; +export * from "./Dialog"; diff --git a/src/stories/layout-elements/Dialog.stories.tsx b/src/stories/layout-elements/Dialog.stories.tsx new file mode 100644 index 000000000..ec5ab7f74 --- /dev/null +++ b/src/stories/layout-elements/Dialog.stories.tsx @@ -0,0 +1,21 @@ +import type { Meta, StoryObj } from "@storybook/react"; + +import { Dialog } from "components"; +import SimpleDialog from "./helpers/SimpleDialog"; + +const meta: Meta = { + title: "UI/Layout/Dialog", + component: Dialog, + parameters: { + sourceLink: + "https://github.com/tremorlabs/tremor/tree/main/src/components/layout-elements/Dialog", + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + render: SimpleDialog, + parameters: {}, +}; diff --git a/src/stories/layout-elements/helpers/SimpleDialog.tsx b/src/stories/layout-elements/helpers/SimpleDialog.tsx new file mode 100644 index 000000000..1e00fc85b --- /dev/null +++ b/src/stories/layout-elements/helpers/SimpleDialog.tsx @@ -0,0 +1,28 @@ +import React, { useState } from "react"; +import { Dialog, DialogPanel, Button, Title } from "components"; + +const SimpleDialog = () => { + const [isOpen, setIsOpen] = useState(false); + return ( + <> +
+ +
+ setIsOpen(val)} static={true}> + + Account Created Successfully + Your account has been created successfully. You can now login to your account. For more + information, please contact us. +
+ +
+
+
+ + ); +}; +export default SimpleDialog; diff --git a/src/tests/layout-elements/Dialog.test.tsx b/src/tests/layout-elements/Dialog.test.tsx new file mode 100644 index 000000000..4058ed172 --- /dev/null +++ b/src/tests/layout-elements/Dialog.test.tsx @@ -0,0 +1,19 @@ +import React from "react"; +import { act, render } from "@testing-library/react"; + +import { Dialog, DialogPanel } from "components"; + +describe("Dialog", () => { + test("renders the Dialog component", async () => { + const { findByText } = render( + {}}> + Test + , + ); + await act(async () => { + await new Promise((resolve) => setTimeout(resolve, 300)); + }); + const message = await findByText("Test"); + expect(message.textContent).toBe("Test"); + }); +});