# Toast Notification

> In-app toast notification with variant, duration, and dismissible flag.

- Name: `toast-notification`
- Categories: notification
- Detail page: https://open-types.dev/types/toast-notification

## Install

```bash
# Types only
npx shadcn add @open-types/toast-notification

# Types + Zod v4 validators
npx shadcn add @open-types/toast-notification-zod

# Types + real-world examples
npx shadcn add @open-types/toast-notification-examples
```

## Types

```typescript
export type ToastVariant = "info" | "success" | "warning" | "error";

export interface ToastAction {
  label: string;
  url?: string;
}

export interface ToastNotification {
  id?: string;
  variant: ToastVariant;
  title: string;
  description?: string;
  duration?: number;
  dismissible?: boolean;
  action?: ToastAction;
}
```

## Zod validator

```typescript
import * as z from "zod";
import type {
  ToastAction,
  ToastNotification,
  ToastVariant,
} from "../types/toast-notification";

export const toastVariantSchema = z.enum(["info", "success", "warning", "error"]) satisfies z.ZodType<ToastVariant>;

export const toastActionSchema = z.object({
  label: z.string().min(1, { error: "Action label is required" }),
  url: z.url({ error: "Action URL must be a valid URL" }).optional(),
}) satisfies z.ZodType<ToastAction>;

export const toastNotificationSchema = z.object({
  id: z.string().optional(),
  variant: toastVariantSchema,
  title: z.string().min(1, { error: "Title is required" }),
  description: z.string().optional(),
  duration: z.number().int({ error: "Duration must be a whole number" }).min(0, {
    error: "Duration cannot be negative",
  }).optional(),
  dismissible: z.boolean().optional(),
  action: toastActionSchema.optional(),
}) satisfies z.ZodType<ToastNotification>;

export type {
  ToastAction,
  ToastNotification,
  ToastVariant,
} from "../types/toast-notification";
```

## Examples

```typescript
// Source: hand-crafted; modeled after sonner/shadcn-ui toast props
import type {
  ToastVariant,
  ToastAction,
  ToastNotification,
} from "../types/toast-notification";

export const toastVariantExamples = {
  info: "info",
  success: "success",
  warning: "warning",
  error: "error",
} as const satisfies Record<string, ToastVariant>;

export const toastActionExamples = {
  withUrl: { label: "View details", url: "https://app.example.com/items/42" } satisfies ToastAction,
  labelOnly: { label: "Undo" } satisfies ToastAction,
  retry: { label: "Retry", url: "https://app.example.com/retry" } satisfies ToastAction,
} as const;

export const toastNotificationExamples = {
  successFull: {
    id: "toast_01HABCDEF",
    variant: "success",
    title: "Saved",
    description: "Your changes were saved successfully.",
    duration: 4000,
    dismissible: true,
    action: { label: "Undo" },
  } satisfies ToastNotification,
  errorPersistent: {
    variant: "error",
    title: "Failed to save",
    description: "An unexpected error occurred. Please try again.",
    duration: 0,
    dismissible: true,
    action: { label: "Retry", url: "https://app.example.com/retry" },
  } satisfies ToastNotification,
  warningWithUrl: {
    variant: "warning",
    title: "Quota almost reached",
    description: "You have used 95% of your monthly quota.",
    action: { label: "Upgrade", url: "https://app.example.com/billing" },
  } satisfies ToastNotification,
  infoMinimal: {
    variant: "info",
    title: "Heads up",
  } satisfies ToastNotification,
  ephemeral: {
    variant: "info",
    title: "Copied to clipboard",
    duration: 1500,
    dismissible: false,
  } satisfies ToastNotification,
} as const;
```
