58 lines · 1.7 KB · TypeScript
RawDownload
"use client"; import type { ToastManagerAddOptions } from "@base-ui/react/toast";import type { ComponentPropsWithoutRef, ReactNode } from "react"; import type { ThreadToastData } from "./toast"; export type StackedThreadToastOptions = {  type: "error" | "warning" | "success" | "info" | "loading";  title: ReactNode;  description?: ReactNode;  timeout?: number;  priority?: "low" | "high";  actionProps?: ComponentPropsWithoutRef<"button">;  /** Merged into `data`; `actionLayout` is always forced to `"stacked-end"` by the helper. */  actionVariant?: ThreadToastData["actionVariant"];  data?: Omit<ThreadToastData, "actionLayout">;}; /** * Thread toast using the stacked body + bottom action row (copy for errors, CTA on its own row). */export function stackedThreadToast(  options: StackedThreadToastOptions,): ToastManagerAddOptions<ThreadToastData> {  const { type, title, description, timeout, priority, actionProps, actionVariant, data } = options;   // Helper-owned `actionLayout` must win over any caller-provided `data`, so spread  // the caller's data first and apply `actionLayout: "stacked-end"` last.  const mergedData: ThreadToastData = {    ...(data !== undefined ? data : {}),    actionLayout: "stacked-end",  };  if (actionVariant !== undefined) {    mergedData.actionVariant = actionVariant;  }   const payload: ToastManagerAddOptions<ThreadToastData> = {    type,    title,    data: mergedData,  };   if (description !== undefined) {    payload.description = description;  }  if (timeout !== undefined) {    payload.timeout = timeout;  }  if (priority !== undefined) {    payload.priority = priority;  }  if (actionProps !== undefined) {    payload.actionProps = actionProps;  }   return payload;}