{
  "generatedFrom": "alert.contract.json",
  "component": "Alert",
  "slug": "alert",
  "group": "Feedback",
  "tier": "leaf-lit",
  "summary": "An inline, contextual feedback banner — info, success, warning, error, or branding — in regular/small sizes, with an optional full-width banner mode and a trailing action.",
  "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/aha-alert';",
    "element": "aha-alert",
    "registers": "aha-alert"
  },
  "feeds": {
    "doc": "https://ahaslides-product.github.io/ahaslides-design/alert/index.html",
    "md": "https://ahaslides-product.github.io/ahaslides-design/alert/alert.md",
    "agentJson": "https://ahaslides-product.github.io/ahaslides-design/alert.agent.json",
    "llms": "https://ahaslides-product.github.io/ahaslides-design/alert.llms.txt",
    "index": "https://ahaslides-product.github.io/ahaslides-design/llms.txt"
  },
  "recommendedSnippet": "html",
  "vibeCode": "Emit the HTML snippet by default — <aha-alert> is a standard custom element that renders on open — React/Vue are thin adapters over the same element. Paste into an .html file and it renders with no build step.",
  "frameworks": {
    "react": {
      "via": "web-component",
      "ref": "aha-alert"
    },
    "vue": {
      "via": "web-component",
      "ref": "aha-alert"
    },
    "html": {
      "via": "web-component",
      "ref": "aha-alert",
      "runnable": "paste-and-run — no build step, renders on open"
    }
  },
  "props": [
    {
      "name": "type",
      "type": "info | success | warning | error | branding",
      "default": "info",
      "desc": "Tone + status icon + surface/border tokens"
    },
    {
      "name": "heading",
      "type": "string",
      "default": "—",
      "desc": "Optional bold title above the message"
    },
    {
      "name": "size",
      "type": "regular | small",
      "default": "regular",
      "desc": "Compact padding + type scale"
    },
    {
      "name": "banner",
      "type": "boolean",
      "default": "false",
      "desc": "Full-width, square-cornered edge-to-edge page notice"
    },
    {
      "name": "closable",
      "type": "boolean",
      "default": "false",
      "desc": "Shows a dismiss control (✕ chrome)"
    },
    {
      "name": "hide-icon",
      "type": "boolean",
      "default": "false",
      "desc": "Suppresses the leading status icon (the showIcon toggle)"
    },
    {
      "name": "slot=\"action\"",
      "type": "slot",
      "default": "—",
      "desc": "Trailing action — a button or link"
    },
    {
      "name": "close",
      "type": "CustomEvent",
      "default": "—",
      "desc": "Composed event when the banner is dismissed"
    }
  ],
  "tokens": [
    "bg-informative",
    "border-info",
    "color-info",
    "bg-positive",
    "text-positive",
    "border-success",
    "bg-warning",
    "text-warning",
    "border-warning",
    "bg-negative",
    "text-negative",
    "border-error",
    "bg-accent",
    "border-focus",
    "color-primary",
    "text-default",
    "icon-muted",
    "radius-default"
  ],
  "spec": [
    {
      "label": "Box",
      "value": "flex row, gap 10 · padding 10 14 · radius 8 · 1px tonal border"
    },
    {
      "label": "Text",
      "value": "Plus Jakarta 14/1.5; heading SemiBold 600"
    },
    {
      "label": "Info",
      "value": "bg #F4F8FF, border #BFD2FF, icon #9BB3E9"
    },
    {
      "label": "Success",
      "value": "bg #D8FAEF, border #16C49A, icon/text #13A181"
    },
    {
      "label": "Warning",
      "value": "bg #FFF5F0, border #FF7747, icon/text #E65B29"
    },
    {
      "label": "Error",
      "value": "bg #FFF1F0, border #F5222D, icon/text #F5222D"
    },
    {
      "label": "Branding",
      "value": "bg-accent #F9F5FF, border-focus #D3B4FF, icon/text color-primary #6A1EBB"
    },
    {
      "label": "Small",
      "value": "padding 6 10 · gap 8 · 13px text · 16px glyph"
    },
    {
      "label": "Banner",
      "value": "full-width, square (radius 0), border on the bottom edge only"
    },
    {
      "label": "Action",
      "value": "trailing slot=\"action\" for a button/link"
    },
    {
      "label": "Icon",
      "value": "status glyph via <aha-icon> (system-info / system-check-circle / system-warning-circle / system-x-circle / system-sparkle)"
    }
  ],
  "opinion": {
    "whenToUse": [
      {
        "what": "Alert",
        "when": "a persistent, inline message tied to a region of the page (a form warning, a page-level notice)"
      },
      {
        "what": "Toast",
        "when": "a brief, transient confirmation of an action that then disappears"
      },
      {
        "what": "Notification",
        "when": "a richer, stacking message with a title + description, often from a background event"
      }
    ],
    "note": "Keep the message to one or two lines; lead with what happened, then what to do. Reserve error for real failures — over-using red trains people to ignore it.",
    "dsv3": "COVERED — enumerated from the DS V3 Figma sets (Alert + Alert-banner, fileKey MwjvUjVI0HnfwD9EwPXRAy): five types (info · success · warning · error · branding), regular + small sizes, an optional heading + description, a showIcon toggle (hide-icon), a closable ✕, a trailing action slot, and a full-width square banner mode (the separate Alert-banner set). Tones bound to the DS V3 semantic families — bg-informative/positive/warning/negative + matching border/text tokens; branding on bg-accent + border-focus + color-primary. Radius on the scale (radius-default = 8). The status glyph is a real DS icon summoned by name, never an inline SVG."
  },
  "surfaces": [
    "editor",
    "dashboard",
    "settings",
    "audience"
  ],
  "snippets": {
    "html": "<!-- Paste-and-run: save as .html and open in a browser. No build step.\n     <aha-alert> is the SAME shared custom element React and Vue consume — here in its\n     native form. Importing it also registers <aha-icon> for the status glyph. Theming\n     comes only from the --aha-* tokens in tokens.css. -->\n<link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/gh/ahaslides-product/ahaslides-design@master/lib/tokens.css\">\n<script type=\"module\">\n  import 'https://cdn.jsdelivr.net/gh/ahaslides-product/ahaslides-design@master/lib/aha-alert.js';   // registers <aha-alert> (+ <aha-icon>)\n</script>\n\n<div style=\"display:flex; flex-direction:column; gap:12px; max-width:520px\">\n  <aha-alert type=\"info\" heading=\"Heads up\">Your poll closes in 5 minutes.</aha-alert>\n  <aha-alert type=\"success\" size=\"small\">Slide saved.</aha-alert>\n  <aha-alert type=\"warning\" heading=\"Almost at the limit\">You have used 9 of 10 slides on the Free plan.</aha-alert>\n  <aha-alert type=\"error\" closable id=\"err\">Upload failed — the file is over 20&nbsp;MB.</aha-alert>\n  <aha-alert type=\"branding\" heading=\"New: AI slide generation\">\n    Turn a prompt into a full deck.\n    <button slot=\"action\">Try it</button>\n  </aha-alert>\n</div>\n\n<!-- banner = full-width, square-cornered page notice (drop it at the top of the layout) -->\n<aha-alert type=\"warning\" banner closable>Scheduled maintenance tonight 22:00–23:00 UTC.</aha-alert>\n\n<script>\n  document.getElementById('err').addEventListener('close', () => console.log('alert dismissed'));\n</script>\n",
    "react": "import '@ahaslides-product/design/aha-alert';   // registers <aha-alert> (+ <aha-icon>)\nimport { useRef, useEffect } from 'react';\n\n// React 18 needs a thin wrapper for the composed `close` event; React 19 can bind onClose directly.\nfunction AhaAlert({ type, heading, size, banner, hideIcon, closable, onClose, action, children }) {\n  const ref = useRef();\n  useEffect(() => {\n    const el = ref.current;\n    const h = () => onClose?.();\n    el.addEventListener('close', h);\n    return () => el.removeEventListener('close', h);\n  });\n  return (\n    <aha-alert\n      ref={ref}\n      type={type}\n      {...(heading ? { heading } : {})}\n      {...(size ? { size } : {})}\n      {...(banner ? { banner: '' } : {})}\n      {...(hideIcon ? { 'hide-icon': '' } : {})}\n      {...(closable ? { closable: '' } : {})}\n    >\n      {children}\n      {action ? <span slot=\"action\">{action}</span> : null}\n    </aha-alert>\n  );\n}\n\n// usage\n<AhaAlert type=\"success\" heading=\"Saved\">Your changes are live.</AhaAlert>\n<AhaAlert type=\"branding\" heading=\"New: AI slides\" action={<button>Try it</button>}>Turn a prompt into a deck.</AhaAlert>\n<AhaAlert type=\"warning\" banner closable onClose={() => setBanner(null)}>Scheduled maintenance tonight.</AhaAlert>\n<AhaAlert type=\"error\" size=\"small\" closable onClose={() => setBanner(null)}>Upload failed — try a smaller file.</AhaAlert>\n",
    "vue": "// main.ts — register the element + mark aha-* as custom elements\nimport '@ahaslides-product/design/aha-alert';   // registers <aha-alert> (+ <aha-icon>)\napp.config.compilerOptions.isCustomElement = (tag) => tag.startsWith('aha-');\n\n// Component.vue\n<script setup>\nimport { ref } from 'vue';\nconst banner = ref(true);\n</script>\n\n<template>\n  <aha-alert type=\"success\" heading=\"Saved\">Your changes are live.</aha-alert>\n  <aha-alert type=\"branding\" heading=\"New: AI slides\">\n    Turn a prompt into a deck.\n    <button slot=\"action\">Try it</button>\n  </aha-alert>\n  <aha-alert type=\"error\" size=\"small\">Upload failed — try a smaller file.</aha-alert>\n  <aha-alert\n    v-if=\"banner\"\n    type=\"warning\"\n    banner\n    closable\n    @close=\"banner = false\"\n  >\n    Scheduled maintenance tonight 22:00–23:00 UTC.\n  </aha-alert>\n</template>\n"
  }
}
