import type { JSX } from "@solidjs/web"; import type { Accessor } from "solid-js"; import { useToastProviderContext } from "./provider/toast-provider-context"; /** * Shape of a single toast instance in the queue. Mirrors Base UI React's * `ToastObject` with Solid-flavored `JSX.Element` replacing React's * `ReactNode`. */ export interface ToastObject { id: string; title?: JSX.Element | string | undefined; description?: JSX.Element | string | undefined; type?: string | undefined; timeout?: number | undefined; priority?: "low" | "high" | undefined; transitionStatus?: "starting" | "ending" | undefined; updateKey?: number | undefined; limited?: boolean | undefined; height?: number | undefined; onClose?: (() => void) | undefined; onRemove?: (() => void) | undefined; actionProps?: | (JSX.IntrinsicElements["button"] & { children?: JSX.Element }) | undefined; data?: Data | undefined; } export interface ToastManagerAddOptions extends Omit, "id" | "height" | "limited" | "updateKey"> { id?: string | undefined; } export interface ToastManagerUpdateOptions extends Partial< Omit< ToastObject, "id" | "height" | "transitionStatus" | "limited" | "updateKey" > > {} export interface ToastManagerPromiseOptions { loading: string | ToastManagerUpdateOptions; success: | string | ToastManagerUpdateOptions | ((result: Value) => string | ToastManagerUpdateOptions); error: | string | ToastManagerUpdateOptions | ((error: unknown) => string | ToastManagerUpdateOptions); } export interface UseToastManagerReturnValue { /** * Reactive accessor for the current toast list. Readers that need the * latest queue should call `toasts()` inside a reactive scope. */ toasts: Accessor[]>; add: (options: ToastManagerAddOptions) => string; close: (id?: string) => void; update: (id: string, options: ToastManagerUpdateOptions) => void; promise: ( value: Promise, options: ToastManagerPromiseOptions, ) => Promise; } /** * Hook: returns the ambient ``'s queue + mutators. * * Port notes: * * - React's `useMemo` wrapping is unnecessary — the underlying store is a * stable object and its mutator functions are stable for the provider's * lifetime. * - `toasts` is an accessor (not a plain array snapshot) so callers stay * reactive across add/close/update. */ export function useToastManager< Data extends object = object, >(): UseToastManagerReturnValue { const store = useToastProviderContext(); return { toasts: store.toasts as Accessor[]>, add: store.addToast as UseToastManagerReturnValue["add"], close: store.closeToast, update: store.updateToast as UseToastManagerReturnValue["update"], promise: store.promiseToast as UseToastManagerReturnValue["promise"], }; }