{
  "generatedFrom": "toast.contract.json",
  "component": "Toast",
  "slug": "toast",
  "group": "Feedback",
  "tier": "composite-antd",
  "summary": "A brief, auto-dismissing confirmation of an action — rendered through antd's message API.",
  "install": {
    "package": "@ahaslides-product/design",
    "registry": "https://npm.pkg.github.com",
    "scope": "@ahaslides-product",
    "auth": "Published to GitHub Packages — needs a GitHub token with read:packages. Configure the @ahaslides-product scope in .npmrc before installing.",
    "npmrc": "@ahaslides-product:registry=https://npm.pkg.github.com\n//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}   # a GitHub token with read:packages",
    "command": "npm i @ahaslides-product/design",
    "tokenLayer": "import '@ahaslides-product/design/tokens.css';",
    "import": "import '@ahaslides-product/design/toast-theme';",
    "element": null,
    "registers": null
  },
  "feeds": {
    "doc": "https://ahaslides-product.github.io/ahaslides-design/toast/index.html",
    "md": "https://ahaslides-product.github.io/ahaslides-design/toast/toast.md",
    "agentJson": "https://ahaslides-product.github.io/ahaslides-design/toast.agent.json",
    "llms": "https://ahaslides-product.github.io/ahaslides-design/toast.llms.txt",
    "index": "https://ahaslides-product.github.io/ahaslides-design/llms.txt"
  },
  "recommendedSnippet": "html",
  "vibeCode": "Emit the HTML snippet by default — a CDN-React runnable page (React + antd loaded from a CDN, no build step) — React/Vue use the same shared-themed DataTable via your bundler. Paste into an .html file and it renders with no build step.",
  "frameworks": {
    "react": {
      "package": "antd",
      "major": 6
    },
    "vue": {
      "package": "ant-design-vue",
      "major": 4
    },
    "html": {
      "via": "cdn-react",
      "runnable": "paste-and-run — React + antd loaded from a CDN, no build step"
    }
  },
  "props": [
    {
      "name": "type",
      "type": "success | info | warning | error | loading",
      "default": "info",
      "desc": "Status glyph + tone"
    },
    {
      "name": "content",
      "type": "string",
      "default": "—",
      "desc": "The message text"
    },
    {
      "name": "duration",
      "type": "number",
      "default": "3",
      "desc": "Seconds on screen; 0 keeps it until dismissed"
    },
    {
      "name": "onClose",
      "type": "() => void",
      "default": "—",
      "desc": "Fires after the toast leaves"
    }
  ],
  "tokens": [
    "colorPrimary",
    "borderRadius",
    "colorText",
    "Message.contentBg"
  ],
  "spec": [
    {
      "label": "Surface",
      "value": "white elevated pill · radius 8 · ink #1A1A1A text"
    },
    {
      "label": "Position",
      "value": "top-centre, floating"
    },
    {
      "label": "Duration",
      "value": "3s default (0 = sticky)"
    },
    {
      "label": "Status",
      "value": "success / info / warning / error / loading"
    }
  ],
  "opinion": {
    "whenToUse": [
      {
        "what": "Toast",
        "when": "confirming a quick action succeeded (saved, copied, sent) with nothing to act on"
      },
      {
        "what": "Notification",
        "when": "a richer message with a title + description, or one the user may need later"
      },
      {
        "what": "Alert",
        "when": "a persistent, inline message tied to a region of the page"
      }
    ],
    "note": "One line, past tense, no title. Never put an action inside a toast that disappears — if the user must respond, use a Notification or a Modal.",
    "dsv3": "COVERED — antd v6 message API, themed by the shared toastTheme (white pill · radius 8 · ink #1A1A1A text · top-centre). Matrix: type × { success, info, warning, error, loading } — each rendered via the message.useMessage() hook + contextHolder inside <ConfigProvider> (the DS forbids the static message.success(), which bypasses the theme). duration (3s default, 0 = sticky) is the second axis. Verified via Figma search_design_system against the DS V3 message set (Component/MD-Message text style — 'toast, alert, message')."
  },
  "surfaces": [
    "editor",
    "dashboard",
    "settings"
  ],
  "snippets": {
    "html": "<!-- Paste-and-run: save as .html and open in a browser. No build step, no bundler.\n     Toast is a COMPOSITE (antd's message API, no framework-free element), so its HTML form is a\n     CDN-React page — React + antd load from a CDN (esm.sh) and mount on open. It consumes the\n     SAME shared `toastTheme` the React/Vue wrappers use, so it renders the DS V3 look (white\n     pill, radius 8, ink text). Keeps antd's built-in enter/leave motion.\n     No JSX here (JSX needs a compiler) — we use React.createElement via the `h` alias. -->\n<div id=\"root\"></div>\n<script type=\"module\">\n  import React from 'https://esm.sh/react@18';\n  import { createRoot } from 'https://esm.sh/react-dom@18/client';\n  import { ConfigProvider, message, Button, Space } from 'https://esm.sh/antd@6?deps=react@18,react-dom@18';\n  import { toastTheme } from 'https://cdn.jsdelivr.net/gh/ahaslides-product/ahaslides-design@master/lib/toast-theme.js';\n\n  const h = React.createElement;\n\n  function App() {\n    // v6: the hook + ctx so every toast consumes the theme. Static message.success() is FORBIDDEN.\n    const [api, ctx] = message.useMessage();\n    return h(ConfigProvider, { theme: toastTheme },\n      ctx,\n      h(Space, { wrap: true },\n        h(Button, { type: 'primary', onClick: () => api.success('Slide saved') }, 'Save'),\n        h(Button, { onClick: () => api.info('Link copied to clipboard') }, 'Copy link'),\n        h(Button, { onClick: () => api.warning('You are near the slide limit') }, 'Warn'),\n        h(Button, { danger: true, onClick: () => api.error('Upload failed') }, 'Fail'),\n        h(Button, { onClick: () => api.loading('Saving your changes…') }, 'Save (async)')\n      )\n    );\n  }\n  // type ∈ { success, info, warning, error, loading }; duration defaults to 3s (0 = sticky).\n  // Same shared theme the React/Vue wrappers pass to ConfigProvider.\n  createRoot(document.getElementById('root')).render(h(App));\n</script>\n",
    "react": "import { ConfigProvider, message, Button, Space } from 'antd';   // antd v6\nimport { toastTheme } from '@ahaslides-product/design/toast-theme';\n\nfunction Toasts() {\n  // v6: use the hook so every toast consumes the ConfigProvider theme.\n  // The static message.success() is FORBIDDEN — it renders outside the provider and drops the theme.\n  const [api, contextHolder] = message.useMessage();\n  return (\n    <ConfigProvider theme={toastTheme}>\n      {contextHolder}\n      <Space wrap>\n        <Button type=\"primary\" onClick={() => api.success('Slide saved')}>Save</Button>\n        <Button onClick={() => api.info('Link copied to clipboard')}>Copy link</Button>\n        <Button onClick={() => api.warning('You are near the slide limit')}>Warn</Button>\n        <Button danger onClick={() => api.error('Upload failed')}>Fail</Button>\n        <Button onClick={() => api.loading('Saving your changes…')}>Save (async)</Button>\n      </Space>\n    </ConfigProvider>\n  );\n}\n// type ∈ { success, info, warning, error, loading }; duration defaults to 3s (0 = sticky).\n// One shared toastTheme → the DS V3 look; keeps antd's built-in enter/leave motion.\n",
    "vue": "<script setup>\nimport { ConfigProvider, message, Button, Space } from 'ant-design-vue';   // ant-design-vue v4\nimport { toastTheme } from '@ahaslides-product/design/toast-theme';\n\n// v4: use the hook so every toast consumes the ConfigProvider theme.\n// The static message.success() is FORBIDDEN — it renders outside the provider and drops the theme.\nconst [messageApi, contextHolder] = message.useMessage();\n</script>\n\n<template>\n  <a-config-provider :theme=\"toastTheme\">\n    <component :is=\"contextHolder\" />\n    <a-space wrap>\n      <a-button type=\"primary\" @click=\"messageApi.success('Slide saved')\">Save</a-button>\n      <a-button @click=\"messageApi.info('Link copied to clipboard')\">Copy link</a-button>\n      <a-button @click=\"messageApi.warning('You are near the slide limit')\">Warn</a-button>\n      <a-button danger @click=\"messageApi.error('Upload failed')\">Fail</a-button>\n      <a-button @click=\"messageApi.loading('Saving your changes…')\">Save (async)</a-button>\n    </a-space>\n  </a-config-provider>\n</template>\n<!-- type ∈ { success, info, warning, error, loading }; duration defaults to 3s (0 = sticky).\n     The SAME toastTheme as React → one DS V3 look across both vendor libraries. -->\n",
    "theme": "// @ahaslides-product/design/toast-theme — declared ONCE, consumed by both tiers.\nimport { toastTheme } from '@ahaslides-product/design/toast-theme';\n\nexport const toastTheme = {\n  token: {\n    colorPrimary: '#6A1EBB',\n    borderRadius: 8,\n    colorText: '#1A1A1A',\n    colorBgElevated: '#FFFFFF',\n    fontFamily: 'var(--aha-font-product, \"Plus Jakarta Sans\", sans-serif)',\n  },\n  components: {\n    Message: {\n      contentBg: '#FFFFFF',     // white elevated surface\n      contentPadding: '9px 12px',\n    },\n  },\n};\n"
  }
}
