Skip to content

Instantly share code, notes, and snippets.

@enrique26
Forked from HectorBlisS/Naive_Dialog_Demo.tsx
Last active January 7, 2023 00:03
Show Gist options
  • Save enrique26/430e8868d08b46ddad831407b4825eef to your computer and use it in GitHub Desktop.
Save enrique26/430e8868d08b46ddad831407b4825eef 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
);
const title = Children.toArray(children).find(
(child: any) => child.type === Title
);
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>
)}
</>
);
};
type TitleProps = {
children?: ReactNode;
}
export const Title = ({ children }: TitleProps) => {
return (
<span className="absolute left-4 top-2 ">{children}</span>
);
}
Dialog.CloseButton = CloseButton;
Dialog.Title = Title;
Dialog.Overlay = Overlay;
Dialog.Content = Content;
Dialog.Footer = Footer;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment