{
  "generatedFrom": "segmented.contract.json",
  "component": "Segmented",
  "slug": "segmented",
  "group": "Data Entry",
  "tier": "leaf-lit",
  "summary": "Switch between a few mutually-exclusive options inline — labels, leading icons, or icon-only, in three sizes.",
  "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-segmented';",
    "element": "aha-segmented",
    "registers": "aha-segmented"
  },
  "feeds": {
    "doc": "https://ahaslides-product.github.io/ahaslides-design/segmented/index.html",
    "md": "https://ahaslides-product.github.io/ahaslides-design/segmented/segmented.md",
    "agentJson": "https://ahaslides-product.github.io/ahaslides-design/segmented.agent.json",
    "llms": "https://ahaslides-product.github.io/ahaslides-design/segmented.llms.txt",
    "index": "https://ahaslides-product.github.io/ahaslides-design/llms.txt"
  },
  "recommendedSnippet": "html",
  "vibeCode": "Emit the HTML snippet by default — <aha-segmented> 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-segmented"
    },
    "vue": {
      "via": "web-component",
      "ref": "aha-segmented"
    },
    "html": {
      "via": "web-component",
      "ref": "aha-segmented",
      "runnable": "paste-and-run — no build step, renders on open"
    }
  },
  "props": [
    {
      "name": "options",
      "type": "string | JSON array",
      "default": "—",
      "desc": "Pipe labels \"Day|Week|Month\" OR items [{value,label?,icon?,disabled?,ariaLabel?}]"
    },
    {
      "name": "value",
      "type": "string",
      "default": "first option",
      "desc": "Selected option value"
    },
    {
      "name": "size",
      "type": "'small' | 'medium' | 'large'",
      "default": "medium",
      "desc": "Height/padding/font/radius scale"
    },
    {
      "name": "block",
      "type": "boolean",
      "default": "false",
      "desc": "Full-width; options flex-equal"
    },
    {
      "name": "disabled",
      "type": "boolean",
      "default": "false",
      "desc": "Dims and disables the whole control"
    },
    {
      "name": "change",
      "type": "CustomEvent<{value,index}>",
      "default": "—",
      "desc": "Composed event; read e.detail.value"
    }
  ],
  "tokens": [
    "gray-20",
    "gray-100",
    "bg-container",
    "text-secondary",
    "text-default",
    "text-disabled",
    "color-primary",
    "radius-xs",
    "radius-sm",
    "radius-default",
    "radius-lg",
    "font-product",
    "motion-mid",
    "ease-in-out",
    "ease-in-out-circ"
  ],
  "spec": [
    {
      "label": "Track",
      "value": "gray-20 #F7F7F7, radius 8 (sm 6 · lg 12), pad 2"
    },
    {
      "label": "Thumb",
      "value": "bg-container #FFFFFF, radius 6, slides on select"
    },
    {
      "label": "Segment",
      "value": "medium h32 pad 0 16 · small h24 12/12px · large h40 20/16px, SemiBold 600"
    },
    {
      "label": "Content",
      "value": "label · leading icon (16) + label · icon-only (aria-label required)"
    },
    {
      "label": "Selected",
      "value": "text-default #1A1A1A over the thumb"
    },
    {
      "label": "Disabled",
      "value": "per-option or whole control → text-disabled, not-allowed"
    },
    {
      "label": "Block",
      "value": "full-width track, options flex-equal"
    }
  ],
  "opinion": {
    "whenToUse": [
      {
        "what": "Segmented",
        "when": "2–4 short, mutually-exclusive views or modes that switch in place"
      },
      {
        "what": "Tabs",
        "when": "navigating between larger content panels"
      },
      {
        "what": "Select",
        "when": "one option from a longer list that needn't be all visible"
      }
    ],
    "note": "Keep labels to one word where possible and the option count small (2–4). Icon-only options MUST carry an aria-label. It is a single-select control — for a magnitude use Rate or a Slider.",
    "dsv3": "COVERED — enumerated from the DS V3 Segmented component-set taxonomy: Segmented-Group (the control), Segmented-Item (label · leading icon + label · icon-only, plus selected/disabled states), Form-Item/Segmented-radio. The family carries three sizes (small · medium · large), a block full-width mode, per-option and whole-control disabled, and icon-only items. Token layer: track gray-20, thumb bg-container white with a soft shadow, selected label text-default; radius from the 4/6/8/12 scale by size. The thumb is a persistent node moved by transform via the shared motion tokens — no subtree rebuild on select."
  },
  "surfaces": [
    "editor",
    "dashboard",
    "settings"
  ],
  "snippets": {
    "html": "<!-- Paste-and-run: save as .html and open in a browser. No build step.\n     <aha-segmented> is the SAME shared custom element React and Vue consume.\n     `options` is pipe-separated labels OR a JSON array of {value,label?,icon?,disabled?,ariaLabel?};\n     `size` is small|medium|large, `block` stretches full-width. Emits a composed `change` event. -->\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/icons.js';         // <aha-icon> (leading/icon-only glyphs)\n  import 'https://cdn.jsdelivr.net/gh/ahaslides-product/ahaslides-design@master/lib/aha-segmented.js'; // registers <aha-segmented>\n</script>\n\n<!-- Simple pipe-string form -->\n<aha-segmented id=\"range\" options=\"Day|Week|Month\" value=\"Week\"></aha-segmented>\n\n<!-- Rich form — leading icons, a disabled option, large size -->\n<aha-segmented size=\"large\" value=\"week\"\n  options='[\n    {\"value\":\"day\",\"label\":\"Day\",\"icon\":\"system-calendar-dot\"},\n    {\"value\":\"week\",\"label\":\"Week\",\"icon\":\"system-calendar-dots\"},\n    {\"value\":\"month\",\"label\":\"Month\",\"icon\":\"system-table\"},\n    {\"value\":\"year\",\"label\":\"Year\",\"disabled\":true}\n  ]'></aha-segmented>\n\n<script>\n  // Plain DOM — no framework. Read e.detail.value off the composed CustomEvent.\n  document.getElementById('range').addEventListener('change', (e) => {\n    console.log('range:', e.detail.value);\n  });\n</script>\n",
    "react": "import '@ahaslides-product/design/aha-segmented';   // registers <aha-segmented>\nimport '@ahaslides-product/design/icons';           // registers <aha-icon> (leading/icon-only glyphs)\nimport { useRef, useEffect } from 'react';\n\n// React 18 needs a thin wrapper; React 19 can use <aha-segmented> directly.\n// `options` is a pipe-string OR a JSON array of {value,label?,icon?,disabled?,ariaLabel?}.\nfunction AhaSegmented({ options, value, size, block, disabled, onChange }) {\n  const ref = useRef();\n  useEffect(() => {\n    const el = ref.current;\n    el.value = value;\n    const h = (e) => onChange?.(e.detail.value);   // composed CustomEvent\n    el.addEventListener('change', h);\n    return () => el.removeEventListener('change', h);\n  });\n  const opts = Array.isArray(options) && typeof options[0] === 'object'\n    ? JSON.stringify(options)          // rich items → JSON string attribute\n    : [].concat(options).join('|');    // labels → pipe string\n  return <aha-segmented ref={ref} options={opts} size={size} block={block || undefined} disabled={disabled || undefined} />;\n}\n\n// usage — rich items with leading icons\n<AhaSegmented\n  size=\"large\"\n  value={range}\n  onChange={setRange}\n  options={[\n    { value: 'day', label: 'Day', icon: 'system-calendar-dot' },\n    { value: 'week', label: 'Week', icon: 'system-calendar-dots' },\n    { value: 'month', label: 'Month', icon: 'system-table' },\n    { value: 'year', label: 'Year', disabled: true },\n  ]}\n/>\n",
    "vue": "// main.ts — register the elements + mark aha-* as custom elements\nimport '@ahaslides-product/design/aha-segmented';\nimport '@ahaslides-product/design/icons';   // <aha-icon> for leading/icon-only glyphs\napp.config.compilerOptions.isCustomElement = (tag) => tag.startsWith('aha-');\n\n// Component.vue\n<script setup>\nimport { ref } from 'vue';\nconst range = ref('week');\n// `options` is a pipe-string OR a JSON array of {value,label?,icon?,disabled?,ariaLabel?}\nconst options = JSON.stringify([\n  { value: 'day', label: 'Day', icon: 'system-calendar-dot' },\n  { value: 'week', label: 'Week', icon: 'system-calendar-dots' },\n  { value: 'month', label: 'Month', icon: 'system-table' },\n  { value: 'year', label: 'Year', disabled: true },\n]);\n</script>\n\n<template>\n  <aha-segmented\n    :options=\"options\"\n    size=\"large\"\n    :value.prop=\"range\"\n    @change=\"range = $event.detail.value\"\n  />\n</template>\n"
  }
}
