From 44af9e16e4bf3b92c9a4fa0e779197f4f9ecb237 Mon Sep 17 00:00:00 2001 From: Abhinav Chadaga Date: Tue, 12 Mar 2024 00:01:56 -0500 Subject: [PATCH] feat: abhinavchadaga/reusable-popup-prompt (#148) * feat: some work on popup prompt * feat: add some stuff * feat: reusable prompt component Takes a title, description, and button children. * fix: pr feedback * fix: import ReactElement --- src/stories/components/Prompt.stories.tsx | 105 ++++++++++++++++++ src/views/components/common/Prompt/Prompt.tsx | 65 +++++++++++ 2 files changed, 170 insertions(+) create mode 100644 src/stories/components/Prompt.stories.tsx create mode 100644 src/views/components/common/Prompt/Prompt.tsx diff --git a/src/stories/components/Prompt.stories.tsx b/src/stories/components/Prompt.stories.tsx new file mode 100644 index 00000000..c9a21bb3 --- /dev/null +++ b/src/stories/components/Prompt.stories.tsx @@ -0,0 +1,105 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Button } from '@views/components/common/Button/Button'; +import type { PromptDialogProps } from '@views/components/common/Prompt/Prompt'; +import PromptDialog from '@views/components/common/Prompt/Prompt'; +import Text from '@views/components/common/Text/Text'; +import React from 'react'; + +const meta = { + title: 'Components/Common/Prompt', + component: PromptDialog, + parameters: { + layout: 'centered', + }, + tags: ['autodocs'], + argTypes: { + isOpen: { control: 'boolean' }, + title: { control: 'object' }, + content: { control: 'object' }, + children: { control: 'object' }, + }, +} satisfies Meta; +export default meta; + +const PromptDialogWithButton = ({ children, ...args }: PromptDialogProps) => { + const [isOpen, setIsOpen] = React.useState(false); + const handleOpen = () => setIsOpen(true); + const handleClose = () => setIsOpen(false); + const { title, content } = args; + + const childrenWithHandleClose: React.ReactElement[] = children.map(child => { + if (child.type === Button) { + return React.cloneElement(child, { onClick: () => handleClose() } as React.HTMLAttributes); + } + return child; + }); + + return ( +
+ + + {childrenWithHandleClose} + +
+ ); +}; + +export const AreYouSure: StoryObj = { + render: args => , + args: { + title: Are you sure?, + content: ( + + Deleting Main Schedule is permanent and will remove all added courses and schedules. + + ), + children: [ + , + , + ], + }, +}; + +export const YouHave10ActiveSchedules: StoryObj = { + render: args => , + args: { + title: You have 10 active schedules!, + content: ( + + To encourage organization, please consider removing some unused schedules you may have. + + ), + children: [ + , + ], + }, +}; + +export const WelcomeToUTRPV2: StoryObj = { + render: args => , + args: { + title: Welcome to UTRP V2!, + content: ( + + You may have already began planning your Summer or Fall schedule. To migrate your courses into v2.0 + please select “Migrate,” or start fresh. + + ), + children: [ + , + , + ], + }, +}; diff --git a/src/views/components/common/Prompt/Prompt.tsx b/src/views/components/common/Prompt/Prompt.tsx new file mode 100644 index 00000000..302b4b0a --- /dev/null +++ b/src/views/components/common/Prompt/Prompt.tsx @@ -0,0 +1,65 @@ +import { Dialog, Transition } from '@headlessui/react'; +import type { ReactElement } from 'react'; +import React from 'react'; + +import type { Button } from '../Button/Button'; +import type Text from '../Text/Text'; + +/** + * Props for the PromptDialog component. + */ +export interface PromptDialogProps { + isOpen: boolean; + onClose: () => void; + title: ReactElement; + content: ReactElement; + children?: ReactElement[]; +} + +/** + * A reusable dialog component that can be used to display a prompt to the user. + * @param {PromptDialogProps} props.isOpen - Whether the dialog is open or not. + * @param {Function} props.onClose - A function to call when the user exits the dialog. + * @param {React.ReactElement} props.title - The title of the dialog. + * @param {React.ReactElement} props.content - The content of the dialog. + * @param {React.ReactElement[]} props.children - The buttons to display in the dialog. + */ +function PromptDialog({ isOpen, onClose, title, content, children }: PromptDialogProps) { + return ( + + + + + + ); +} + +export default PromptDialog;