import { useState } from "react"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { useArgs } from "storybook/preview-api"; import { CloseIcon } from "../icons"; import { Dialog, EDialogWidth } from "./root"; const meta = { title: "Components/Dialog", component: Dialog, subcomponents: { DialogPanel: Dialog.Panel, DialogTitle: Dialog.Title, }, args: { children: null, open: false, onOpenChange: () => {}, }, parameters: { layout: "centered", }, tags: ["autodocs"], render(args) { const [{ open }, updateArgs] = useArgs(); const setOpen = (value: boolean) => updateArgs({ open: value }); return ( <> setOpen(true)} className="rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600"> Open Dialog {open && ( Dialog Title This is the dialog content. You can put any content here. setOpen(false)} className="rounded bg-gray-200 px-4 py-2 text-sm hover:bg-gray-300" > Cancel setOpen(false)} className="rounded bg-blue-500 px-4 py-2 text-sm text-white hover:bg-blue-600" > Confirm )} > ); }, } satisfies Meta; export default meta; type Story = StoryObj; export const Default: Story = { args: { children: null, }, }; export const TopPosition: Story = { render(args) { const [open, setOpen] = useState(args.open); return ( <> setOpen(true)} className="rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600"> Open Dialog (Top) {open && ( Top Positioned Dialog This dialog appears at the top of the screen instead of centered. setOpen(false)} className="rounded bg-gray-200 px-4 py-2 text-sm hover:bg-gray-300" > Close )} > ); }, }; export const SmallWidth: Story = { render(args) { const [open, setOpen] = useState(args.open); return ( <> setOpen(true)} className="rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600"> Open Small Dialog {open && ( Small Dialog This is a small dialog. setOpen(false)} className="rounded bg-blue-500 px-4 py-2 text-sm text-white hover:bg-blue-600" > Close )} > ); }, }; export const LargeWidth: Story = { render(args) { const [open, setOpen] = useState(args.open); return ( <> setOpen(true)} className="rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600"> Open Large Dialog {open && ( Large Dialog This is a large dialog with more horizontal space for content. setOpen(false)} className="rounded bg-blue-500 px-4 py-2 text-sm text-white hover:bg-blue-600" > Close )} > ); }, }; export const WithCloseButton: Story = { render(args) { const [open, setOpen] = useState(args.open); return ( <> setOpen(true)} className="rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600"> Open Dialog with Close Button {open && ( Dialog with Close Button setOpen(false)} className="rounded-full p-1 hover:bg-gray-100"> This dialog has a close button in the header. )} > ); }, }; export const ConfirmationDialog: Story = { render(args) { const [open, setOpen] = useState(args.open); const handleConfirm = () => { alert("Confirmed!"); setOpen(false); }; return ( <> setOpen(true)} className="rounded bg-red-500 px-4 py-2 text-white hover:bg-red-600"> Delete Item {open && ( Confirm Deletion Are you sure you want to delete this item? This action cannot be undone. setOpen(false)} className="rounded bg-gray-200 px-4 py-2 text-sm hover:bg-gray-300" > Cancel Delete )} > ); }, }; export const FormDialog: Story = { render(args) { const [open, setOpen] = useState(args.open); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); alert("Form submitted!"); setOpen(false); }; return ( <> setOpen(true)} className="rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600"> Open Form {open && ( Create New Item Name Description setOpen(false)} className="rounded bg-gray-200 px-4 py-2 text-sm hover:bg-gray-300" > Cancel Create )} > ); }, }; export const ScrollableContent: Story = { render(args) { const [open, setOpen] = useState(args.open); return ( <> setOpen(true)} className="rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600"> Open Scrollable Dialog {open && ( Scrollable Content {Array.from({ length: 20 }, (_, i) => ( Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ))} setOpen(false)} className="rounded bg-blue-500 px-4 py-2 text-sm text-white hover:bg-blue-600" > Close )} > ); }, }; export const AllWidths: Story = { render() { const [openWidth, setOpenWidth] = useState(null); const widths = [ { width: EDialogWidth.SM, label: "Small" }, { width: EDialogWidth.MD, label: "Medium" }, { width: EDialogWidth.LG, label: "Large" }, { width: EDialogWidth.XL, label: "XL" }, { width: EDialogWidth.XXL, label: "2XL" }, { width: EDialogWidth.XXXL, label: "3XL" }, { width: EDialogWidth.XXXXL, label: "4XL" }, ]; return ( {widths.map(({ width, label }) => ( setOpenWidth(width)} className="rounded bg-blue-500 px-4 py-2 text-sm text-white hover:bg-blue-600" > {label} ))} {widths.map(({ width, label }) => ( setOpenWidth(null)}> {label} Dialog This dialog uses the {label} width variant. setOpenWidth(null)} className="rounded bg-blue-500 px-4 py-2 text-sm text-white hover:bg-blue-600" > Close ))} ); }, };
This is the dialog content. You can put any content here.
This dialog appears at the top of the screen instead of centered.
This is a small dialog.
This is a large dialog with more horizontal space for content.
This dialog has a close button in the header.
Are you sure you want to delete this item? This action cannot be undone.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
This dialog uses the {label} width variant.