Skip to content

Instantly share code, notes, and snippets.

@HectorBlisS
Created January 6, 2023 00:04
Show Gist options
  • Save HectorBlisS/db8e05c5d166516a58eafeee7ba8687f to your computer and use it in GitHub Desktop.
Save HectorBlisS/db8e05c5d166516a58eafeee7ba8687f to your computer and use it in GitHub Desktop.
import { Children, createContext, useContext, type ReactNode } from "react";
const dialogContext = createContext<Record<string, any>>({});
type DialogProps = {
isOpen?: boolean;
children: any;
onClose?: () => void;
};
export default function Dialog({
onClose,
children,
isOpen = true,
}: DialogProps) {
if (!children || !isOpen) return null;
const overlay = Children.toArray(children).find(
(child: any) => child.type === Overlay
);
const content = Children.toArray(children).find(
(child: any) => child.type === Content
);
const closeButton = Children.toArray(children).find(
(child: any) => child.type === CloseButton
);
const footer = Children.toArray(children).find(
(child: any) => child.type === Footer
);
return (
<dialogContext.Provider value={{ onClose }}>
<section className="absolute flex min-h-screen items-center justify-center">
{overlay}
<div className="absolute min-w-max rounded bg-white px-8 pt-12 pb-4">
{closeButton}
{content}
<hr className="mt-8 mb-2 w-full border-t border-slate-300" />
{footer}
</div>
</section>
</dialogContext.Provider>
);
}
type OverlayProps = {
bgColor?: string;
props?: any;
};
export const Overlay = ({ bgColor, ...props }: OverlayProps) => {
const classname = `fixed top-0 left-0 h-screen w-full opacity-50 ${
bgColor ? bgColor : "bg-black"
}`;
return <div {...props} className={classname} />;
};
type CloseButtonProps = {
children?: ReactNode;
};
export const CloseButton = ({ ...props }: CloseButtonProps) => {
const { onClose } = useContext(dialogContext);
return (
<button onClick={onClose} {...props} className="absolute right-4 top-2 ">
{props.children || <span>&#10005;</span>}
</button>
);
};
type ContentProps = {
children: ReactNode;
};
export const Content = ({ children }: ContentProps) => {
return <>{children}</>;
};
type FooterProps = {
children?: ReactNode;
};
export const Footer = ({ children }: FooterProps) => {
const { onClose } = useContext(dialogContext);
return (
<>
{children || (
<button
onClick={onClose}
className="ml-auto block rounded-md bg-blue-500 px-4 py-2 text-white"
>
Cerrar
</button>
)}
</>
);
};
Dialog.CloseButton = CloseButton;
Dialog.Overlay = Overlay;
Dialog.Content = Content;
Dialog.Footer = Footer;
@enrique26
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment