diff --git a/src/components/ui/Dialog.stories.tsx b/src/components/ui/Dialog.stories.tsx new file mode 100644 index 0000000..62fdede --- /dev/null +++ b/src/components/ui/Dialog.stories.tsx @@ -0,0 +1,276 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { + Dialog, + DialogTrigger, + DialogContent, + DialogHeader, + DialogFooter, + DialogTitle, + DialogDescription, + DialogClose, + Button, + Input, + Label, +} from "./index"; + +function DialogDemo() { + return ( + + }> + Edit Profile + + + + Edit profile + + Make changes to your profile here. Click save when you're done. + + +
+
+ + +
+
+ + +
+
+ + }> + Cancel + + + +
+
+ ); +} + +function DialogCustomCloseDemo() { + return ( + + }> + Custom Close Button + + + + Custom Close + + This dialog uses a custom close button in the footer instead of the + default X button. + + +
+

+ You can customize the close behavior by using the DialogClose + component anywhere inside the dialog. +

+
+ + }> + Close + + +
+
+ ); +} + +function DialogNoCloseButtonDemo() { + return ( + + }> + No Close Button + + + + No Close Button + + This dialog has no close button. Click outside or press Escape to + close it. + + +
+

+ Use showCloseButton={false} to + hide the default close button. +

+
+
+
+ ); +} + +function DialogScrollableDemo() { + return ( + + }> + Scrollable Content + + + + Terms of Service + + Please read the following terms carefully. + + +
+
+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim + ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. +

+

+ Duis aute irure dolor in reprehenderit in voluptate velit esse + cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat + cupidatat non proident, sunt in culpa qui officia deserunt mollit + anim id est laborum. +

+

+ Sed ut perspiciatis unde omnis iste natus error sit voluptatem + accusantium doloremque laudantium, totam rem aperiam, eaque ipsa + quae ab illo inventore veritatis et quasi architecto beatae vitae + dicta sunt explicabo. +

+

+ Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit + aut fugit, sed quia consequuntur magni dolores eos qui ratione + voluptatem sequi nesciunt. +

+

+ Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, + consectetur, adipisci velit, sed quia non numquam eius modi tempora + incidunt ut labore et dolore magnam aliquam quaerat voluptatem. +

+

+ Ut enim ad minima veniam, quis nostrum exercitationem ullam + corporis suscipit laboriosam, nisi ut aliquid ex ea commodi + consequatur? Quis autem vel eum iure reprehenderit qui in ea + voluptate velit esse quam nihil molestiae consequatur. +

+

+ At vero eos et accusamus et iusto odio dignissimos ducimus qui + blanditiis praesentium voluptatum deleniti atque corrupti quos + dolores et quas molestias excepturi sint occaecati cupiditate non + provident. +

+

+ Similique sunt in culpa qui officia deserunt mollitia animi, id est + laborum et dolorum fuga. Et harum quidem rerum facilis est et + expedita distinctio. +

+
+
+ + }> + Decline + + + +
+
+ ); +} + +function DialogStickyFooterDemo() { + return ( + + }> + Sticky Footer + + + + Edit Settings + + Configure your application settings below. The footer stays fixed at + the bottom. + + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + }> + Cancel + + + +
+
+ ); +} + +const meta = { + title: "UI/Dialog", + component: Dialog, + parameters: { layout: "centered" }, + tags: ["autodocs"], +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + render: () => , +}; + +export const CustomCloseButton: Story = { + render: () => , +}; + +export const NoCloseButton: Story = { + render: () => , +}; + +export const ScrollableContent: Story = { + render: () => , +}; + +export const StickyFooter: Story = { + render: () => , +}; diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx new file mode 100644 index 0000000..fbc53b3 --- /dev/null +++ b/src/components/ui/dialog.tsx @@ -0,0 +1,146 @@ +"use client" + +import * as React from "react" +import { Dialog as DialogPrimitive } from "@base-ui/react/dialog" + +import { cn } from "@/lib/utils" +import { Button } from "@/components/ui/button" +import { XIcon } from "lucide-react" +import { useThemeOptional, defaultCssVariables } from "@/providers" + +function Dialog({ ...props }: DialogPrimitive.Root.Props) { + return +} + +function DialogTrigger({ ...props }: DialogPrimitive.Trigger.Props) { + return +} + +function DialogClose({ ...props }: DialogPrimitive.Close.Props) { + return +} + +function DialogPortal({ ...props }: DialogPrimitive.Portal.Props) { + return +} + +function DialogOverlay({ + className, + ...props +}: DialogPrimitive.Backdrop.Props) { + return ( + + ) +} + +function DialogContent({ + className, + children, + showCloseButton = true, + ...props +}: DialogPrimitive.Popup.Props & { + showCloseButton?: boolean +}) { + const theme = useThemeOptional() + const mode = theme?.mode ?? "light" + const cssVariables = theme?.cssVariables ?? defaultCssVariables + return ( + + + + {children} + {showCloseButton && ( + + } + > + + Close + + )} + + + ) +} + +function DialogHeader({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function DialogFooter({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function DialogTitle({ + className, + ...props +}: DialogPrimitive.Title.Props) { + return ( + + ) +} + +function DialogDescription({ + className, + ...props +}: DialogPrimitive.Description.Props) { + return ( + + ) +} + +export { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogOverlay, + DialogPortal, + DialogTitle, + DialogTrigger, +} diff --git a/src/components/ui/index.ts b/src/components/ui/index.ts index 011e712..722eb83 100644 --- a/src/components/ui/index.ts +++ b/src/components/ui/index.ts @@ -152,6 +152,20 @@ export { // ColorPicker component export { ColorPicker, type ColorPickerProps } from "./color-picker"; +// Dialog component +export { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogOverlay, + DialogPortal, + DialogTitle, + DialogTrigger, +} from "./dialog"; + // Sheet component export { Sheet, diff --git a/src/index.ts b/src/index.ts index 3a51233..fa3e8d8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -72,6 +72,17 @@ export { CurrencyInput, DesignSystemSection, // DataViews DataViews, + // Dialog + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogOverlay, + DialogPortal, + DialogTitle, + DialogTrigger, // DropdownMenu DropdownMenu, DropdownMenuCheckboxItem,