import React, { DetailedHTMLProps, HTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
import Card from "./Card";
import { X } from "lucide-react";
import ReactDOM from "react-dom";
import Span from "../layout/Span";
export const ToastStyles = ["normal", "success", "error"] as const;
export const ToastColors = ToastStyles;
export type TWUIToastProps = DetailedHTMLProps<
HTMLAttributes,
HTMLDivElement
> & {
open?: boolean;
setOpen?: React.Dispatch>;
closeDelay?: number;
color?: (typeof ToastStyles)[number];
};
let interval: any;
let timeout: any;
/**
* # Toast Component
* @className twui-toast-root
* @className twui-toast
* @className twui-toast-success
* @className twui-toast-error
*/
export default function Toast({
open,
setOpen,
closeDelay = 4000,
color,
...props
}: TWUIToastProps) {
const [ready, setReady] = React.useState(false);
const IDName = "twui-toast-root";
React.useEffect(() => {
const toastRoot = document.getElementById(IDName);
if (toastRoot) {
setReady(true);
} else {
const newToastRootEl = document.createElement("div");
newToastRootEl.id = IDName;
document.body.appendChild(newToastRootEl);
setReady(true);
}
}, []);
React.useEffect(() => {
if (!ready || !open) return;
timeout = setTimeout(() => {
setOpen?.(false);
}, closeDelay);
return function () {
setOpen?.(false);
};
}, [ready, open]);
if (!ready) return null;
if (!open) return null;
return ReactDOM.createPortal(
{
window.clearTimeout(timeout);
}}
onMouseLeave={(e) => {
timeout = setTimeout(() => {
setOpen?.(false);
}, closeDelay);
}}
>
{
setOpen?.(false);
}}
>
{props.children}
,
document.getElementById(IDName) as HTMLElement
);
}