{
  "generatedFrom": "autocomplete.contract.json",
  "component": "AutoComplete",
  "slug": "autocomplete",
  "group": "Data Entry",
  "tier": "composite-antd",
  "summary": "Free-text input with suggestions as you type — search boxes, tag entry, known-but-open fields — rendered through the shared AutoComplete.",
  "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/autocomplete-theme';",
    "element": null,
    "registers": null
  },
  "feeds": {
    "doc": "https://ahaslides-product.github.io/ahaslides-design/autocomplete/index.html",
    "md": "https://ahaslides-product.github.io/ahaslides-design/autocomplete/autocomplete.md",
    "agentJson": "https://ahaslides-product.github.io/ahaslides-design/autocomplete.agent.json",
    "llms": "https://ahaslides-product.github.io/ahaslides-design/autocomplete.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": "options",
      "type": "{ value, label? }[] | { label, options }[]",
      "default": "[]",
      "desc": "Suggestions shown as the user types — flat, or grouped ({ label, options }) for section headers"
    },
    {
      "name": "value",
      "type": "string",
      "default": "—",
      "desc": "Current free-text value"
    },
    {
      "name": "size",
      "type": "'small' | 'default' | 'large'",
      "default": "'default'",
      "desc": "Control height — 24 / 32 / 40, matching the DS V3 Input size set"
    },
    {
      "name": "status",
      "type": "'error' | 'warning'",
      "default": "—",
      "desc": "Validation state — red / amber border, same as the DS V3 Input"
    },
    {
      "name": "disabled",
      "type": "boolean",
      "default": "false",
      "desc": "Non-interactive, muted control"
    },
    {
      "name": "allowClear",
      "type": "boolean",
      "default": "false",
      "desc": "Shows a clear (×) affordance once there's a value"
    },
    {
      "name": "onSearch",
      "type": "(text) => void",
      "default": "—",
      "desc": "Fires as the query changes — fetch/filter suggestions"
    },
    {
      "name": "onSelect",
      "type": "(value) => void",
      "default": "—",
      "desc": "Fires when a suggestion is chosen"
    },
    {
      "name": "filterOption",
      "type": "boolean | (input, option) => boolean",
      "default": "true",
      "desc": "Client-side filter; set false when onSearch fetches server-side"
    },
    {
      "name": "placeholder",
      "type": "string",
      "default": "—",
      "desc": "Hint shown when empty"
    }
  ],
  "tokens": [
    "colorPrimary",
    "borderRadius",
    "controlHeight",
    "colorBorder",
    "Select.optionSelectedBg",
    "Select.optionActiveBg"
  ],
  "spec": [
    {
      "label": "Control",
      "value": "height 32 · radius 8 · 1px #E3E3E3 border"
    },
    {
      "label": "Sizes",
      "value": "small 24 · default 32 · large 40 (DS V3 Input set)"
    },
    {
      "label": "Status",
      "value": "error #F5222D · warning #FAAD14 border"
    },
    {
      "label": "Focus",
      "value": "brand #6A1EBB border"
    },
    {
      "label": "Active option",
      "value": "#F7F7F7 (gray-20) row"
    },
    {
      "label": "Selected option",
      "value": "brand-tint #F9F5FF row"
    },
    {
      "label": "Placeholder",
      "value": "#8A8A8A"
    }
  ],
  "opinion": {
    "whenToUse": [
      {
        "what": "AutoComplete",
        "when": "free text where suggestions help but the user may type their own value"
      },
      {
        "what": "Select",
        "when": "the value MUST come from a known set — don't allow free text"
      },
      {
        "what": "Input",
        "when": "free text with no suggestions to offer"
      }
    ],
    "note": "Filter suggestions on the query, don't dump the whole list. AutoComplete allows values outside the options — if the value must be from the set, use Select instead.",
    "dsv3": "COVERED — antd v6 AutoComplete (Select internals) themed by the shared autocompleteTheme. Matrix: size (small 24 · default 32 · large 40) × status (none · error · warning) × disabled / allowClear, plus flat vs grouped ({ label, options }) suggestions, live filtering, and custom option render. DS V3 ships no standalone AutoComplete component — it inherits the Input/Select primitive set (size × rest/focus/disabled/error), so the matrix mirrors that set; verified via Figma search_design_system against the DS V3 Input/Select set (fileKey MwjvUjVI0HnfwD9EwPXRAy). The interactive preview drives Size · Status · State (Clearable/Disabled/Plain) with a live grouped filter."
  },
  "surfaces": [
    "editor",
    "dashboard",
    "settings"
  ],
  "snippets": {
    "html": "<!-- Paste-and-run: save as .html and open in a browser. No build step, no bundler.\n     AutoComplete is a COMPOSITE (antd, no framework-free element), so its HTML form is a CDN-React\n     page — React + antd load from a CDN (esm.sh) and mount on open. It consumes the SAME shared\n     `autocompleteTheme` the React/Vue wrappers use, so it renders the DS V3 look (32px control,\n     radius 8, #E3E3E3 border, brand focus, brand-tint option). size / status / allowClear / grouped\n     options all theme through the same token set.\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, AutoComplete } from 'https://esm.sh/antd@6?deps=react@18,react-dom@18';\n  import { autocompleteTheme } from 'https://cdn.jsdelivr.net/gh/ahaslides-product/ahaslides-design@master/lib/autocomplete-theme.js';\n\n  const h = React.createElement;\n  // Grouped ({ label, options }) suggestions — flat works too.\n  const options = [\n    { label: 'Live polls', options: [{ value: 'Poll' }, { value: 'Quiz' }, { value: 'Word cloud' }] },\n    { label: 'Discussion', options: [{ value: 'Q&A' }, { value: 'Open-ended' }] },\n  ];\n\n  createRoot(document.getElementById('root')).render(\n    h(ConfigProvider, { theme: autocompleteTheme },\n      h(AutoComplete, {\n        options,\n        size: 'default',          // 'small' | 'default' | 'large' → 24 / 32 / 40\n        status: undefined,        // 'error' | 'warning' for validation\n        allowClear: true,         // × affordance once there's a value\n        placeholder: 'Type a slide type',\n        filterOption: (input, opt) => opt.value.toLowerCase().includes(input.toLowerCase()),\n        style: { width: 260 },\n      })\n    )\n  );\n</script>\n",
    "react": "import { ConfigProvider, AutoComplete } from 'antd';   // antd v6\nimport { autocompleteTheme } from '@ahaslides-product/design/autocomplete-theme';\n\n// Flat or grouped ({ label, options }) suggestions — both theme the same.\nconst options = [\n  { label: 'Live polls',  options: [{ value: 'Poll' }, { value: 'Quiz' }, { value: 'Word cloud' }] },\n  { label: 'Discussion',  options: [{ value: 'Q&A' }, { value: 'Open-ended' }] },\n];\n\n<ConfigProvider theme={autocompleteTheme}>\n  <AutoComplete\n    options={options}\n    size=\"default\"          // 'small' | 'default' | 'large' → 24 / 32 / 40\n    status={error ? 'error' : undefined}   // 'error' | 'warning' — DS V3 Input states\n    allowClear              // × affordance once there's a value\n    disabled={false}\n    placeholder=\"Type a slide type\"\n    onSearch={fetchSuggestions}   // fires as the query changes\n    onSelect={setValue}\n    filterOption={(input, opt) => opt.value.toLowerCase().includes(input.toLowerCase())}\n    style={{ width: 260 }}\n  />\n</ConfigProvider>\n// One shared autocompleteTheme → the DS V3 look; AutoComplete allows free text, use Select if the value must be from the set.\n",
    "vue": "<script setup>\nimport { ref } from 'vue';\nimport { ConfigProvider, AutoComplete } from 'ant-design-vue';   // ant-design-vue v4\nimport { autocompleteTheme } from '@ahaslides-product/design/autocomplete-theme';\n\nconst value = ref('');\n// Flat or grouped ({ label, options }) suggestions — both theme the same.\nconst options = ref([\n  { label: 'Live polls', options: [{ value: 'Poll' }, { value: 'Quiz' }, { value: 'Word cloud' }] },\n  { label: 'Discussion', options: [{ value: 'Q&A' }, { value: 'Open-ended' }] },\n]);\n</script>\n\n<template>\n  <a-config-provider :theme=\"autocompleteTheme\">\n    <a-auto-complete\n      v-model:value=\"value\"\n      :options=\"options\"\n      size=\"default\"                    <!-- 'small' | 'default' | 'large' → 24 / 32 / 40 -->\n      :status=\"error ? 'error' : undefined\"  <!-- 'error' | 'warning' -->\n      allow-clear\n      :disabled=\"false\"\n      placeholder=\"Type a slide type\"\n      :filter-option=\"(input, opt) => opt.value.toLowerCase().includes(input.toLowerCase())\"\n      style=\"width: 260px\"\n    />\n  </a-config-provider>\n</template>\n<!-- The SAME autocompleteTheme as React → one DS V3 look across both vendor libraries. -->\n",
    "theme": "// @ahaslides-product/design/autocomplete-theme — declared ONCE, consumed by both tiers.\nimport { autocompleteTheme } from '@ahaslides-product/design/autocomplete-theme';\n\nexport const autocompleteTheme = {\n  token: {\n    colorPrimary: '#6A1EBB',\n    borderRadius: 8,\n    controlHeight: 32,\n    colorBorder: '#E3E3E3',\n    colorTextPlaceholder: '#8A8A8A',\n    fontFamily: 'var(--aha-font-product, \"Plus Jakarta Sans\", sans-serif)',\n  },\n  components: {\n    // AutoComplete renders on Ant's Select internals — theme it through the Select component token.\n    Select: {\n      optionSelectedBg: '#F9F5FF',   // brand-tint selected row\n      optionActiveBg: '#F7F7F7',     // keyboard/hover row\n      borderRadius: 8,\n      controlHeight: 32,\n    },\n  },\n};\n"
  }
}
