Last active
July 2, 2023 06:27
-
-
Save stephyswe/5a95e5a92cc1ad05ad6be99e19fbad30 to your computer and use it in GitHub Desktop.
two files, dialog.tsx (parent), modal.tsx (child)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as DialogPrimitive from "@radix-ui/react-dialog"; | |
import * as React from "react"; | |
import { cn } from "@/lib/utils"; | |
const defaultClasses = { | |
overlay: | |
"fixed inset-0 z-50 bg-background/80 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", | |
content: | |
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 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%] sm:rounded-lg md:w-full", | |
header: "flex flex-col space-y-1.5 text-center sm:text-left", | |
footer: "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", | |
title: "text-lg font-semibold leading-none tracking-tight", | |
description: "text-sm text-muted-foreground", | |
}; | |
type ComponentOrElement = | |
| keyof JSX.IntrinsicElements | |
| React.JSXElementConstructor<any>; | |
interface DialogProps extends React.ComponentProps<any> { | |
className?: string; | |
} | |
function onDialog<P extends DialogProps>( | |
component: ComponentOrElement, | |
defaultClassName: string, | |
displayName?: string | |
) { | |
const ForwardedComponent = React.forwardRef<unknown, P>( | |
({ className, ...props }, ref) => | |
React.createElement(component as string | React.ComponentType<any>, { | |
ref, | |
className: cn(defaultClassName, className), | |
...props, | |
}) | |
); | |
ForwardedComponent.displayName = displayName; | |
return ForwardedComponent; | |
} | |
const { Root, Trigger, Portal, Overlay, Content, Title, Description } = | |
DialogPrimitive; | |
const Dialog = { | |
Root, | |
Trigger, | |
Portal, | |
Overlay: onDialog(Overlay, defaultClasses.overlay, "DialogOverlay"), | |
Content: onDialog(Content, defaultClasses.content, "DialogContent"), | |
Header: onDialog("div", defaultClasses.header), | |
Footer: onDialog("div", defaultClasses.footer), | |
Title: onDialog(Title, defaultClasses.title, "DialogTitle"), | |
Description: onDialog( | |
Description, | |
defaultClasses.description, | |
"DialogDescription" | |
), | |
}; | |
export { Dialog }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use client"; | |
import { Dialog } from "@/components/ui/dialog"; | |
interface ModalProps { | |
title: string; | |
description: string; | |
isOpen: boolean; | |
onClose: () => void; | |
children?: React.ReactNode; | |
} | |
export const Modal: React.FC<ModalProps> = ({ | |
title, | |
description, | |
isOpen, | |
onClose, | |
children, | |
}) => { | |
const onChange = (open: boolean) => { | |
if (!open) { | |
onClose(); | |
} | |
}; | |
return ( | |
<Dialog.Root open={isOpen} onOpenChange={onChange}> | |
<Dialog.Content> | |
<Dialog.Header> | |
<Dialog.Title>{title}</Dialog.Title> | |
<Dialog.Description>{description}</Dialog.Description> | |
</Dialog.Header> | |
<div>{children}</div> | |
</Dialog.Content> | |
</Dialog.Root> | |
); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment