import { createContext, useContext, type ParentProps, Show } from "solid-js" import { createStore } from "solid-js/store" import { useTheme } from "../context/theme" import { useTerminalDimensions } from "@opentui/solid" import { SplitBorder } from "./border" import { TextAttributes } from "@opentui/core" export type ToastOptions = { title?: string message: string variant: "info" | "success" | "warning" | "error" duration: number } type ToastInput = Omit & { duration?: number } export function Toast() { const toast = useToast() const { theme } = useTheme() const dimensions = useTerminalDimensions() return ( {(current) => ( {current().title} {current().message} )} ) } function init() { const [store, setStore] = createStore({ currentToast: null as ToastOptions | null, }) let timeoutHandle: NodeJS.Timeout | null = null const toast = { show(options: ToastInput) { const toastOptions = { ...options, duration: options.duration ?? 5000 } setStore("currentToast", toastOptions) if (timeoutHandle) clearTimeout(timeoutHandle) timeoutHandle = setTimeout(() => { setStore("currentToast", null) }, toastOptions.duration).unref() }, error: (err: any) => { if (err instanceof Error) return toast.show({ variant: "error", message: err.message, }) toast.show({ variant: "error", message: "An unknown error has occurred", }) }, get currentToast(): ToastOptions | null { return store.currentToast }, } return toast } export type ToastContext = ReturnType const ctx = createContext() export function ToastProvider(props: ParentProps) { const value = init() return {props.children} } export function useToast() { const value = useContext(ctx) if (!value) { throw new Error("useToast must be used within a ToastProvider") } return value }