import React, { DetailedHTMLProps, HTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
import { createRoot } from "react-dom/client";
import Card from "./Card";
import { X } from "lucide-react";
import Span from "../layout/Span";
export const ToastStyles = ["normal", "success", "error"] as const;
export const ToastColors = ToastStyles;
type Props = DetailedHTMLProps<
HTMLAttributes,
HTMLDivElement
> & {
open?: boolean;
setOpen?: React.Dispatch>;
closeDelay?: number;
color?: (typeof ToastStyles)[number];
};
/**
* # 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
}: Props) {
if (!open) return null;
const toastEl = (
{
const targetEl = e.target as HTMLElement;
const rootWrapperEl = targetEl.closest(".twui-toast-root");
if (rootWrapperEl) {
rootWrapperEl.parentElement?.removeChild(rootWrapperEl);
setOpen?.(false);
}
}}
>
{props.children}
);
React.useEffect(() => {
const wrapperEl = document.createElement("div");
wrapperEl.className = twMerge(
"fixed z-[200000] bottom-10 right-10",
"flex flex-col items-center justify-center",
"twui-toast-root"
);
document.body.appendChild(wrapperEl);
const root = createRoot(wrapperEl);
root.render(toastEl);
setTimeout(() => {
closeToast({ wrapperEl });
setOpen?.(false);
}, closeDelay);
return function () {
closeToast({ wrapperEl });
};
}, []);
return null;
}
function closeToast({ wrapperEl }: { wrapperEl: HTMLDivElement | null }) {
if (!wrapperEl) return;
wrapperEl.parentElement?.removeChild(wrapperEl);
}