Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dialog improvements #1351

Merged
merged 3 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions src/v2/components/ui/Dialog.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import type { Meta, StoryObj } from "@storybook/react"

import { ComponentProps } from "react"
import {
Dialog,
DialogCloseButton,
DialogContent,
DialogContentProps,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "./Dialog"

const DialogExample = ({
size,
longContent,
showHeader = true,
showFooter,
}: {
size?: DialogContentProps["size"]
longContent?: ComponentProps<typeof DynamicDialogContent>["longContent"]
showHeader?: boolean
showFooter?: boolean
}) => (
<Dialog defaultOpen>
<DialogTrigger>Open dialog</DialogTrigger>
<DialogContent size={size}>
{showHeader && (
<DialogHeader>
<DialogTitle>Awesome dialog</DialogTitle>
<DialogDescription>Less awesome, optional description</DialogDescription>
</DialogHeader>
)}

<DynamicDialogContent longContent={longContent} />

{showFooter && <DialogFooter>Sneaky dialog footer</DialogFooter>}

<DialogCloseButton />
</DialogContent>
</Dialog>
)

const meta: Meta<typeof DialogExample> = {
title: "Design system/Dialog",
component: DialogExample,
}

export default meta

type Story = StoryObj<typeof DialogExample>

export const Default: Story = {
args: {
longContent: false,
size: "md",
showHeader: true,
showFooter: false,
},
argTypes: {
size: {
control: {
type: "select",
},
options: ["sm", "md", "lg", "xl", "2xl", "3xl", "4xl"],
},
},
}

const DynamicDialogContent = ({ longContent }: { longContent?: boolean }) => {
if (!longContent) return <p>This is a simple dialog.</p>

return (
<>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin a luctus
lorem. Etiam aliquam vel est vel lacinia. Nulla vehicula tortor quis erat
pellentesque, et interdum nisl aliquet. Aenean ac malesuada mauris. Aliquam
scelerisque lorem ut metus interdum, ut venenatis orci egestas. In semper
mollis eros lobortis mollis. Praesent vestibulum convallis ipsum at
fermentum. Donec porta facilisis lacus eu dignissim. Proin hendrerit orci
gravida risus commodo fermentum. Donec finibus sapien eu nibh mattis dictum.
Praesent ac tempor odio, et lobortis ex. Donec nec mauris et lorem facilisis
auctor. Maecenas vitae convallis leo.
</p>
<p>
Maecenas maximus felis scelerisque turpis euismod rutrum. Pellentesque a
dolor scelerisque, elementum sapien eu, porta libero. Donec volutpat egestas
tincidunt. Vivamus blandit eros mollis viverra aliquam. Mauris eu turpis id
est gravida finibus. In viverra, elit eget eleifend sagittis, massa quam
faucibus erat, sed mattis odio nunc vitae enim. Donec lacus diam, lobortis at
facilisis in, placerat ut diam. Maecenas sed dui sit amet massa tristique
vulputate non ac erat. Nullam orci urna, finibus eu blandit et, pharetra ac
enim. Donec magna augue, interdum at sollicitudin id, fringilla nec sapien.
In nisl quam, rhoncus blandit ipsum in, volutpat aliquam nisi. Nam accumsan
lobortis ante, at tristique ante vehicula eget. Sed ornare varius velit, ut
ultrices ante auctor non. Cras bibendum, libero sed varius fringilla, quam
lorem fermentum nunc, vitae varius mauris libero sed tortor.
</p>
<p>
Donec ut aliquam massa. Etiam congue turpis at purus tempor maximus. Etiam
semper libero non varius pellentesque. Ut egestas faucibus purus non
faucibus. Duis sed nisi consequat, laoreet nisi in, laoreet purus. Integer
aliquam mi ac metus interdum rhoncus. In ac iaculis quam. Sed eu nibh lectus.
Donec imperdiet vestibulum nisl in facilisis. Sed molestie ipsum eu orci
imperdiet cursus. Morbi sit amet quam mi. Etiam maximus scelerisque orci, id
gravida ligula sagittis in. Maecenas volutpat quam elit, vel vehicula ex
fringilla ac. Aenean risus lectus, pellentesque id est eget, feugiat
hendrerit ligula. Nulla tempor pulvinar lacus, ut euismod tortor.
</p>
</>
)
}
33 changes: 17 additions & 16 deletions src/v2/components/ui/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const DialogOverlay = React.forwardRef<
<DialogPrimitive.Overlay
ref={ref}
className={cn(
"fixed inset-0 z-50 bg-black/50 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
"fixed inset-0 z-50 grid place-items-center overflow-y-auto bg-black/50 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className
)}
{...props}
Expand All @@ -30,7 +30,7 @@ const DialogOverlay = React.forwardRef<
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName

export const dialogContentVariants = cva(
"fixed left-[50%] top-[50%] z-50 grid w-full translate-x-[-50%] translate-y-[-50%] gap-8 rounded-xl bg-card px-10 py-8 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]",
"w-full my-16 relative rounded-xl bg-card shadow-lg p-10 duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
{
variants: {
size: {
Expand Down Expand Up @@ -60,16 +60,17 @@ const DialogContent = React.forwardRef<
DialogContentProps
>(({ size, trapFocus = true, className, children, ...props }, ref) => (
<DialogPortal>
<DialogOverlay />
<FocusScope trapped={trapFocus} loop>
<DialogPrimitive.Content
ref={ref}
className={cn(dialogContentVariants({ size, className }))}
{...props}
>
{children}
</DialogPrimitive.Content>
</FocusScope>
<DialogOverlay>
<FocusScope trapped={trapFocus} loop>
<DialogPrimitive.Content
ref={ref}
className={cn(dialogContentVariants({ size, className }))}
{...props}
>
{children}
</DialogPrimitive.Content>
</FocusScope>
</DialogOverlay>
</DialogPortal>
))
DialogContent.displayName = DialogPrimitive.Content.displayName
Expand All @@ -96,7 +97,7 @@ const DialogHeader = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div className={cn("flex flex-col space-y-1.5", className)} {...props} />
<div className={cn("flex flex-col space-y-1.5 pb-8", className)} {...props} />
)
DialogHeader.displayName = "DialogHeader"

Expand All @@ -106,7 +107,7 @@ const DialogFooter = ({
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
"flex flex-col-reverse pt-8 sm:flex-row sm:justify-end sm:space-x-2",
className
)}
{...props}
Expand All @@ -121,7 +122,7 @@ const DialogTitle = React.forwardRef<
<DialogPrimitive.Title
ref={ref}
className={cn(
"mb-2 font-display text-xl font-bold leading-none tracking-wide",
"font-display text-xl font-bold leading-none tracking-wide",
className
)}
{...props}
Expand All @@ -135,7 +136,7 @@ const DialogDescription = React.forwardRef<
>(({ className, ...props }, ref) => (
<DialogPrimitive.Description
ref={ref}
className={cn("text-muted-foreground", className)}
className={cn("mt-2 text-muted-foreground", className)}
{...props}
/>
))
Expand Down