{
  "generatedFrom": "add-item-button.contract.json",
  "component": "Add Item Button",
  "slug": "add-item-button",
  "group": "Settings",
  "tier": "leaf-lit",
  "summary": "The full-width \"+ Add\" affordance that sits under a settings list (OptionRow / QuestionList) — a dashed, tertiary add row that appends a new item.",
  "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-add-item-button';",
    "element": "aha-add-item-button",
    "registers": "aha-add-item-button"
  },
  "feeds": {
    "doc": "https://ahaslides-product.github.io/ahaslides-design/add-item-button/index.html",
    "md": "https://ahaslides-product.github.io/ahaslides-design/add-item-button/add-item-button.md",
    "agentJson": "https://ahaslides-product.github.io/ahaslides-design/add-item-button.agent.json",
    "llms": "https://ahaslides-product.github.io/ahaslides-design/add-item-button.llms.txt",
    "index": "https://ahaslides-product.github.io/ahaslides-design/llms.txt"
  },
  "recommendedSnippet": "html",
  "vibeCode": "Emit the HTML snippet by default — <aha-add-item-button> 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-add-item-button"
    },
    "vue": {
      "via": "web-component",
      "ref": "aha-add-item-button"
    },
    "html": {
      "via": "web-component",
      "ref": "aha-add-item-button",
      "runnable": "paste-and-run — no build step, renders on open"
    }
  },
  "props": [
    {
      "name": "label",
      "type": "string",
      "default": "Add",
      "desc": "The add-affordance text; carries the accessible name"
    },
    {
      "name": "disabled",
      "type": "boolean",
      "default": "false",
      "desc": "Non-interactive (e.g. at the max item count); muted, no hover, sets aria-disabled"
    },
    {
      "name": "add",
      "type": "CustomEvent<{}>",
      "default": "—",
      "desc": "Composed event fired on click when enabled — the host appends a new item"
    }
  ],
  "tokens": [
    "border",
    "border-disabled",
    "color-primary",
    "bg-container",
    "bg-accent",
    "text-secondary",
    "text-disabled",
    "focus-ring-soft"
  ],
  "spec": [
    {
      "label": "Box",
      "value": "full width (100%) · height 40 · radius 8 · padding 0 12"
    },
    {
      "label": "Border",
      "value": "1px dashed #E3E3E3 (rest)"
    },
    {
      "label": "Content",
      "value": "centered — system-plus 16px + label, 8px gap"
    },
    {
      "label": "Text",
      "value": "Plus Jakarta 14/600, #4A4A4A (secondary)"
    },
    {
      "label": "Hover",
      "value": "border + text → #6A1EBB, #F9F5FF fill (animated)"
    },
    {
      "label": "Focus",
      "value": "#6A1EBB border + 2px soft ring"
    },
    {
      "label": "Disabled",
      "value": "#B5B5B5 text, #EBEBEB border, not-allowed, no hover, aria-disabled"
    }
  ],
  "opinion": {
    "whenToUse": [
      {
        "what": "Add Item Button",
        "when": "append a new row to an editable settings list — options, questions, list items"
      },
      {
        "what": "Button (tertiary)",
        "when": "a standalone action that isn't 'add another row to this list'"
      }
    ],
    "note": "Place it directly under the list it grows, full-width so it reads as part of the stack. Label it with the item noun — 'Add option', 'Add question' — not a bare 'Add' when the context needs it. Disable (don't hide) it at the max count so the ceiling stays discoverable; pair with a tooltip or helper line explaining the limit.",
    "dsv3": "COVERED — the DS V3 settings option-list 'Add' row (§10 of the settings pattern): a full-width dashed tertiary affordance under OptionRow / QuestionList lists. Dashed border + text bind to the DS `border` / `text-secondary` tokens; the hover tint binds to `color-primary` + `bg-accent`; radius 8 on-scale. Motion + focus ring on the persistent button node."
  },
  "surfaces": [
    "editor",
    "settings",
    "dashboard"
  ],
  "snippets": {
    "html": "<!-- Paste-and-run: save as .html and open in a browser. No build step.\n     <aha-add-item-button> is the SAME shared custom element React and Vue consume — here in its\n     native form. Theming comes only from the --aha-* tokens in tokens.css.\n     The + glyph is summoned by name from the DS icon library via <aha-icon>. -->\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-add-item-button.js'; // registers <aha-add-item-button> (also pulls in <aha-icon>)\n</script>\n\n<!-- full-width add row — sits under an editable settings list; disabled = at the max item count -->\n<div style=\"width:320px\">\n  <aha-add-item-button id=\"add\" label=\"Add option\"></aha-add-item-button>\n  <br>\n  <aha-add-item-button label=\"Add option\" disabled></aha-add-item-button>\n</div>\n\n<script>\n  // Plain DOM — no framework. The composed `add` CustomEvent fires on click; append a new item here.\n  let count = 1;\n  document.getElementById('add').addEventListener('add', () => {\n    console.log('add item #', ++count);\n  });\n</script>\n",
    "react": "import '@ahaslides-product/design/aha-add-item-button'; // registers <aha-add-item-button> (also pulls in <aha-icon>)\nimport { useRef, useEffect } from 'react';\n\n// React 18 needs a thin wrapper for the composed `add` event; React 19 can use <aha-add-item-button> directly.\nfunction AhaAddItemButton({ label = 'Add', disabled, onAdd }) {\n  const ref = useRef();\n  useEffect(() => {\n    const el = ref.current;\n    const h = () => onAdd?.();   // composed CustomEvent, no payload\n    el.addEventListener('add', h);\n    return () => el.removeEventListener('add', h);\n  });\n  return (\n    <aha-add-item-button\n      ref={ref}\n      label={label}\n      {...(disabled ? { disabled: '' } : {})}\n    />\n  );\n}\n\n// usage\nfunction OptionList({ options, setOptions, max = 10 }) {\n  return (\n    <>\n      {/* …option rows… */}\n      <AhaAddItemButton\n        label=\"Add option\"\n        disabled={options.length >= max}\n        onAdd={() => setOptions([...options, { text: '' }])}\n      />\n    </>\n  );\n}\n",
    "vue": "// main.ts — register the element + mark aha-* as custom elements\nimport '@ahaslides-product/design/aha-add-item-button'; // registers <aha-add-item-button> (also pulls in <aha-icon>)\napp.config.compilerOptions.isCustomElement = (tag) => tag.startsWith('aha-');\n\n// Component.vue\n<script setup>\nimport { ref, computed } from 'vue';\nconst options = ref([{ text: '' }]);\nconst max = 10;\nconst atMax = computed(() => options.value.length >= max);\n</script>\n\n<template>\n  <!-- full-width add row under the option list; disabled at the max item count -->\n  <!-- …option rows… -->\n  <aha-add-item-button\n    label=\"Add option\"\n    :disabled.prop=\"atMax\"\n    @add=\"options.push({ text: '' })\"\n  />\n</template>\n"
  }
}
