{
  "name": "Toast",
  "source": "src/components/Toast.tsx",
  "propsType": "ToastProps",
  "description": "Toast — Figma `Toast` (820:1655).\n\nNeutral chrome on `surface/raised`; the intent is carried by the icon alone.\nA tinted panel floating over unknown content competes with whatever is\nbehind it, and makes Toast and Alert indistinguishable at a glance.\n\nAUTO-DISMISS PAUSES ON HOVER AND FOCUS. A toast that keeps counting down\nwhile being read or while its action has keyboard focus takes the action\naway mid-reach — WCAG 2.2.1 asks for exactly this. The timer restarts rather\nthan resumes, which is the forgiving direction.",
  "import": "import { Toast } from 'ionbase-ui';",
  "status": "stable",
  "summary": "A transient notification on neutral chrome. Intent is carried by the icon, not by a tinted panel. Show one with `const { toast, dismiss } = useToast()` inside a ToastProvider: `toast({ intent, title, message, action, duration })` queues it and returns its id, and `dismiss(id)` removes it. You rarely render `<Toast>` yourself: the provider renders the queue.",
  "useWhen": [
    "confirming that something the user just did succeeded or failed",
    "the message is short, transient, and not required to complete a task"
  ],
  "useInstead": [
    {
      "when": "the message must stay until the condition is resolved",
      "use": "Alert",
      "why": "a toast disappears, and anything the user must act on should not"
    },
    {
      "when": "the message belongs to one field",
      "use": "Input",
      "why": "Input's error text sits with the field it is about"
    },
    {
      "when": "you need a decision from the user",
      "use": "Modal",
      "why": "a toast offers one action and takes it away on a timer"
    }
  ],
  "variants": {
    "intent": {
      "neutral": {
        "use": "a plain fact with no status attached"
      },
      "primary": {
        "use": "brand-flavoured confirmations"
      },
      "success": {
        "use": "the action completed"
      },
      "warning": {
        "use": "it completed with a caveat worth knowing"
      },
      "error": {
        "use": "it failed — pair with a way to retry"
      },
      "information": {
        "use": "the default — a neutral update"
      }
    }
  },
  "slots": {
    "title": {
      "accepts": "text"
    },
    "message": {
      "accepts": "text"
    },
    "action": {
      "accepts": "{ label, onPress }",
      "note": "exactly one action. A second choice belongs in a Modal, which will still be there"
    }
  },
  "a11y": {
    "guarantees": [
      "auto-dismiss pauses on hover and on focus, and restarts rather than resumes — WCAG 2.2.1, and the forgiving direction",
      "announcement comes from ToastProvider's live region, which is always present rather than appearing with its content"
    ],
    "requires": [
      "rendering inside a ToastProvider — a Toast on its own is not in a live region",
      "`duration={null}` when the message carries an action the user genuinely needs"
    ]
  },
  "antiPatterns": [
    {
      "dont": "a toast for an error the user must fix",
      "why": "it vanishes; the fix does not"
    },
    {
      "dont": "two actions in one toast",
      "why": "a timed choice is not a choice"
    },
    {
      "dont": "stacking several toasts for one operation",
      "why": "the stack covers the page and the last one is the only one read"
    },
    {
      "dont": "calling `useToast().show(...)` or `useToast().success(...)`",
      "why": "neither exists. `useToast()` returns `{ toast, dismiss }`: call `toast({ intent: 'success', title })`"
    }
  ],
  "stylesheet": "src/styles/toast.css",
  "tokens": [
    "--border-subtle",
    "--border-width-default",
    "--border-width-thick",
    "--font-family-sans",
    "--font-weight-medium",
    "--font-weight-regular",
    "--icon-error",
    "--icon-information",
    "--icon-primary",
    "--icon-secondary",
    "--icon-size-md",
    "--icon-success",
    "--icon-warning",
    "--ion-duration-base",
    "--ion-ease-out",
    "--ion-shadow-shadow-lg",
    "--ion-toast-icon",
    "--radius-md",
    "--radius-sm",
    "--ring-focus",
    "--spacing-12",
    "--spacing-16",
    "--spacing-32",
    "--spacing-4",
    "--surface-hover",
    "--surface-raised",
    "--text-default",
    "--text-link",
    "--text-link-hover",
    "--text-secondary",
    "--type-body",
    "--type-body-line-height",
    "--type-body-sm",
    "--type-body-sm-line-height"
  ],
  "props": {
    "onDismiss": {
      "type": "(id: string) => void",
      "required": true,
      "origin": "own"
    },
    "id": {
      "type": "string",
      "required": true,
      "origin": "own"
    },
    "intent": {
      "type": "ToastIntent | undefined",
      "required": false,
      "origin": "own",
      "values": [
        "neutral",
        "primary",
        "success",
        "warning",
        "error",
        "information"
      ],
      "default": "information"
    },
    "title": {
      "type": "React.ReactNode",
      "required": false,
      "origin": "own"
    },
    "message": {
      "type": "React.ReactNode",
      "required": false,
      "origin": "own"
    },
    "action": {
      "type": "{ label: string; onPress: () => void; } | undefined",
      "required": false,
      "origin": "own",
      "description": "One action. A second choice belongs in a dialog, which will still be there."
    },
    "duration": {
      "type": "number | null | undefined",
      "required": false,
      "origin": "own",
      "description": "Milliseconds before auto-dismiss. `null` keeps it until dismissed.",
      "default": 5000
    },
    "dismissLabel": {
      "type": "string | undefined",
      "required": false,
      "origin": "own",
      "default": "Dismiss"
    }
  },
  "propCounts": {
    "own": 8,
    "aria": 0,
    "dom": 0,
    "other": 0
  }
}
